diff --git a/DSView/pv/data/analogsnapshot.cpp b/DSView/pv/data/analogsnapshot.cpp index 23669a7b..415329f8 100644 --- a/DSView/pv/data/analogsnapshot.cpp +++ b/DSView/pv/data/analogsnapshot.cpp @@ -46,7 +46,9 @@ const float AnalogSnapshot::LogEnvelopeScaleFactor = const uint64_t AnalogSnapshot::EnvelopeDataUnit = 64*1024; // bytes AnalogSnapshot::AnalogSnapshot() : - Snapshot(sizeof(uint16_t), 1, 1) + Snapshot(sizeof(uint16_t), 1, 1), + _unit_bytes(1), + _unit_pitch(0) { memset(_envelope_levels, 0, sizeof(_envelope_levels)); } @@ -77,6 +79,9 @@ void AnalogSnapshot::init() for (unsigned int i = 0; i < _channel_num; i++) { for (unsigned int level = 0; level < ScaleStepCount; level++) { _envelope_levels[i][level].length = 0; + _envelope_levels[i][level].ring_length = 0; + // fix hang issue, count should not be clear + //_envelope_levels[i][level].count = 0; _envelope_levels[i][level].data_length = 0; } } @@ -93,17 +98,24 @@ void AnalogSnapshot::clear() void AnalogSnapshot::first_payload(const sr_datafeed_analog &analog, uint64_t total_sample_count, GSList *channels) { _total_sample_count = total_sample_count; + _unit_bytes = (analog.unit_bits + 7) / 8; + assert(_unit_bytes > 0); + assert(_unit_bytes <= sizeof(uint64_t)); _channel_num = 0; for (const GSList *l = channels; l; l = l->next) { sr_channel *const probe = (sr_channel*)l->data; assert(probe); - if (probe->type == SR_CHANNEL_ANALOG && probe->enabled) { + // TODO: data of disabled channels should not be captured. +// if (probe->type == SR_CHANNEL_ANALOG && probe->enabled) { +// _channel_num ++; +// } + if (probe->type == SR_CHANNEL_ANALOG) { _channel_num ++; } } bool isOk = true; - uint64_t size = _total_sample_count * _channel_num * BytesPerSample + sizeof(uint64_t); + uint64_t size = _total_sample_count * _channel_num * _unit_bytes + sizeof(uint64_t); if (size != _capacity) { free_data(); _data = malloc(size); @@ -115,10 +127,15 @@ void AnalogSnapshot::first_payload(const sr_datafeed_analog &analog, uint64_t to envelop_count = ((envelop_count + EnvelopeDataUnit - 1) / EnvelopeDataUnit) * EnvelopeDataUnit; _envelope_levels[i][level].samples = (EnvelopeSample*)malloc(envelop_count * sizeof(EnvelopeSample)); - if (!_envelope_levels[i][level].samples) { + _envelope_levels[i][level].max = (uint8_t *)malloc(envelop_count * _unit_bytes); + _envelope_levels[i][level].min = (uint8_t *)malloc(envelop_count * _unit_bytes); + if (!_envelope_levels[i][level].samples || + !_envelope_levels[i][level].max || + !_envelope_levels[i][level].min) { isOk = false; break; } + _envelope_levels[i][level].count = envelop_count; envelop_count = envelop_count / EnvelopeScaleFactor; } if (!isOk) @@ -152,72 +169,80 @@ 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, analog.unit_pitch); // Generate the first mip-map from the data append_payload_to_envelope_levels(); } -void AnalogSnapshot::append_data(void *data, uint64_t samples) +void AnalogSnapshot::append_data(void *data, uint64_t samples, uint16_t pitch) { - int unit_bytes = BytesPerSample * _channel_num; - if (_sample_count + samples < _total_sample_count) - _sample_count += samples; - else - _sample_count = _total_sample_count; + int bytes_per_sample = _unit_bytes * _channel_num; + if (pitch <= 1) { + if (_sample_count + samples < _total_sample_count) + _sample_count += samples; + else + _sample_count = _total_sample_count; - if (_ring_sample_count + samples > _total_sample_count) { - memcpy((uint8_t*)_data + _ring_sample_count * unit_bytes, - data, (_total_sample_count - _ring_sample_count) * unit_bytes); - _ring_sample_count = (samples + _ring_sample_count - _total_sample_count) % _total_sample_count; - memcpy((uint8_t*)_data, - data, _ring_sample_count * unit_bytes); + if (_ring_sample_count + samples >= _total_sample_count) { + memcpy((uint8_t*)_data + _ring_sample_count * bytes_per_sample, + data, (_total_sample_count - _ring_sample_count) * bytes_per_sample); + data = (uint8_t*)data + (_total_sample_count - _ring_sample_count) * bytes_per_sample; + _ring_sample_count = (samples + _ring_sample_count - _total_sample_count) % _total_sample_count; + memcpy((uint8_t*)_data, + data, _ring_sample_count * bytes_per_sample); + } else { + memcpy((uint8_t*)_data + _ring_sample_count * bytes_per_sample, + data, samples * bytes_per_sample); + _ring_sample_count += samples; + } } else { - memcpy((uint8_t*)_data + _ring_sample_count * unit_bytes, - data, samples * unit_bytes); - _ring_sample_count += samples; + while(samples--) { + if (_unit_pitch == 0) { + if (_sample_count < _total_sample_count) + _sample_count++; + memcpy((uint8_t*)_data + _ring_sample_count * bytes_per_sample, + data, bytes_per_sample); + data = (uint8_t*)data + bytes_per_sample; + _ring_sample_count = (_ring_sample_count + 1) % _total_sample_count; + _unit_pitch = pitch; + } + _unit_pitch--; + } } } -const uint16_t* AnalogSnapshot::get_samples( - int64_t start_sample, int64_t end_sample) const +const uint8_t* AnalogSnapshot::get_samples(int64_t start_sample) const { - (void)end_sample; - assert(start_sample >= 0); assert(start_sample < (int64_t)get_sample_count()); - assert(end_sample >= 0); - assert(end_sample < (int64_t)get_sample_count()); - assert(start_sample <= end_sample); // uint16_t *const data = new uint16_t[end_sample - start_sample]; // memcpy(data, (uint16_t*)_data + start_sample, sizeof(uint16_t) * // (end_sample - start_sample)); // return data; - return (uint16_t*)_data + start_sample * _channel_num; + return (uint8_t*)_data + start_sample * _unit_bytes * _channel_num; } void AnalogSnapshot::get_envelope_section(EnvelopeSection &s, - uint64_t start, uint64_t end, float min_length, int probe_index) const + uint64_t start, int64_t count, float min_length, int probe_index) const { - assert(end <= get_sample_count()); - assert(start <= end); + assert(count >= 0); assert(min_length > 0); - const unsigned int min_level = max((int)floorf(logf(min_length) / - LogEnvelopeScaleFactor) - 1, 0); - const unsigned int scale_power = (min_level + 1) * - EnvelopeScalePower; + const unsigned int min_level = max((int)floorf(logf(min_length) / + LogEnvelopeScaleFactor) - 1, 0); + const unsigned int scale_power = (min_level + 1) * EnvelopeScalePower; start >>= scale_power; - end >>= scale_power; - s.start = start << scale_power; - s.scale = 1 << scale_power; - s.length = end - start; + s.start = start; + s.scale = (1 << scale_power); + s.length = (count >> scale_power); + s.samples_num = _envelope_levels[probe_index][min_level].length; // s.samples = new EnvelopeSample[s.length]; // memcpy(s.samples, _envelope_levels[min_level].samples + start, // s.length * sizeof(EnvelopeSample)); - s.samples = _envelope_levels[probe_index][min_level].samples + start; + s.samples = _envelope_levels[probe_index][min_level].samples; } void AnalogSnapshot::reallocate_envelope(Envelope &e) @@ -241,56 +266,46 @@ void AnalogSnapshot::append_payload_to_envelope_levels() EnvelopeSample *dest_ptr; // Expand the data buffer to fit the new samples - prev_length = e0.length; e0.length = _sample_count / EnvelopeScaleFactor; + prev_length = e0.ring_length; + e0.ring_length = _ring_sample_count / EnvelopeScaleFactor; // Break off if there are no new samples to compute - // if (e0.length == prev_length) - // return; + if (e0.ring_length == prev_length) + return; if (e0.length == 0) return; - if (e0.length == prev_length) - prev_length = 0; reallocate_envelope(e0); dest_ptr = e0.samples + prev_length; // Iterate through the samples to populate the first level mipmap - const uint16_t *const stop_src_ptr = (uint16_t*)_data + - e0.length * EnvelopeScaleFactor * _channel_num; -// for (const uint16_t *src_ptr = (uint16_t*)_data + -// prev_length * EnvelopeScaleFactor; -// src_ptr < end_src_ptr; src_ptr += EnvelopeScaleFactor) -// { -// const EnvelopeSample sub_sample = { -// *min_element(src_ptr, src_ptr + EnvelopeScaleFactor), -// *max_element(src_ptr, src_ptr + EnvelopeScaleFactor), -// }; - -// *dest_ptr++ = sub_sample; -// } - for (const uint16_t *src_ptr = (uint16_t*)_data + - prev_length * EnvelopeScaleFactor * _channel_num + i; - src_ptr < stop_src_ptr; src_ptr += EnvelopeScaleFactor * _channel_num) - { - const uint16_t * begin_src_ptr = - src_ptr; - const uint16_t *const end_src_ptr = - src_ptr + EnvelopeScaleFactor * _channel_num; - + const uint64_t src_size = _total_sample_count * _unit_bytes * _channel_num; + uint64_t e0_sample_num = (e0.ring_length > prev_length) ? e0.ring_length - prev_length : + e0.ring_length + (_total_sample_count / EnvelopeScaleFactor) - prev_length; + uint8_t *src_ptr = (uint8_t*)_data + + (prev_length * EnvelopeScaleFactor * _channel_num + i) * _unit_bytes; + for (uint64_t j = 0; j < e0_sample_num; j++) { + const uint8_t *end_src_ptr = + src_ptr + EnvelopeScaleFactor * _unit_bytes * _channel_num; + if (end_src_ptr >= (uint8_t*)_data + src_size) + end_src_ptr -= src_size; EnvelopeSample sub_sample; - sub_sample.min = *begin_src_ptr; - sub_sample.max = *begin_src_ptr; - begin_src_ptr += _channel_num; - while (begin_src_ptr < end_src_ptr) - { - sub_sample.min = min(sub_sample.min, *begin_src_ptr); - sub_sample.max = max(sub_sample.max, *begin_src_ptr); - begin_src_ptr += _channel_num; + sub_sample.min = *src_ptr; + sub_sample.max = *src_ptr; + src_ptr += _channel_num * _unit_bytes; + while(src_ptr != end_src_ptr) { + sub_sample.min = min(sub_sample.min, *src_ptr); + sub_sample.max = max(sub_sample.max, *src_ptr); + src_ptr += _channel_num * _unit_bytes; + if (src_ptr >= (uint8_t*)_data + src_size) + src_ptr -= src_size; } *dest_ptr++ = sub_sample; + if (dest_ptr >= e0.samples + e0.count) + dest_ptr = e0.samples; } // Compute higher level mipmaps @@ -300,36 +315,40 @@ void AnalogSnapshot::append_payload_to_envelope_levels() const Envelope &el = _envelope_levels[i][level-1]; // Expand the data buffer to fit the new samples - prev_length = e.length; e.length = el.length / EnvelopeScaleFactor; + prev_length = e.ring_length; + e.ring_length = el.ring_length / EnvelopeScaleFactor; // Break off if there are no more samples to computed - // if (e.length == prev_length) - // break; - if (e.length == prev_length) - prev_length = 0; + if (e.ring_length == prev_length) + break; reallocate_envelope(e); // Subsample the level lower level const EnvelopeSample *src_ptr = el.samples + prev_length * EnvelopeScaleFactor; - const EnvelopeSample *const end_dest_ptr = e.samples + e.length; - for (dest_ptr = e.samples + prev_length; - dest_ptr < end_dest_ptr; dest_ptr++) - { - const EnvelopeSample *const end_src_ptr = + const EnvelopeSample *const end_dest_ptr = e.samples + e.ring_length; + dest_ptr = e.samples + prev_length; + while(dest_ptr != end_dest_ptr) { + const EnvelopeSample * end_src_ptr = src_ptr + EnvelopeScaleFactor; + if (end_src_ptr >= el.samples + el.count) + end_src_ptr -= el.count; EnvelopeSample sub_sample = *src_ptr++; - while (src_ptr < end_src_ptr) + while (src_ptr != end_src_ptr) { sub_sample.min = min(sub_sample.min, src_ptr->min); sub_sample.max = max(sub_sample.max, src_ptr->max); src_ptr++; + if (src_ptr >= el.samples + el.count) + src_ptr = el.samples; } - *dest_ptr = sub_sample; + *dest_ptr++ = sub_sample; + if (dest_ptr >= e.samples + e.count) + dest_ptr = e.samples; } } } @@ -350,5 +369,15 @@ int AnalogSnapshot::get_ch_order(int sig_index) return order; } +uint8_t AnalogSnapshot::get_unit_bytes() const +{ + return _unit_bytes; +} + +int AnalogSnapshot::get_scale_factor() const +{ + return EnvelopeScaleFactor; +} + } // namespace data } // namespace pv diff --git a/DSView/pv/data/analogsnapshot.h b/DSView/pv/data/analogsnapshot.h index 798d812a..a4811a08 100644 --- a/DSView/pv/data/analogsnapshot.h +++ b/DSView/pv/data/analogsnapshot.h @@ -43,8 +43,8 @@ class AnalogSnapshot : public Snapshot public: struct EnvelopeSample { - uint16_t min; - uint16_t max; + uint8_t min; + uint8_t max; }; struct EnvelopeSection @@ -52,15 +52,22 @@ public: uint64_t start; unsigned int scale; uint64_t length; + uint64_t samples_num; EnvelopeSample *samples; + uint8_t *max; + uint8_t *min; }; private: struct Envelope { uint64_t length; + uint64_t ring_length; + uint64_t count; uint64_t data_length; EnvelopeSample *samples; + uint8_t *max; + uint8_t *min; }; private: @@ -70,8 +77,6 @@ private: static const float LogEnvelopeScaleFactor; static const uint64_t EnvelopeDataUnit; - static const int BytesPerSample = 2; - public: AnalogSnapshot(); @@ -85,16 +90,19 @@ public: void append_payload(const sr_datafeed_analog &analog); - const uint16_t* get_samples(int64_t start_sample, - int64_t end_sample) const; + const uint8_t *get_samples(int64_t start_sample) const; - void get_envelope_section(EnvelopeSection &s, - uint64_t start, uint64_t end, float min_length, int probe_index) const; + void get_envelope_section(EnvelopeSection &s, + uint64_t start, int64_t count, float min_length, int probe_index) const; int get_ch_order(int sig_index); + uint8_t get_unit_bytes() const; + + int get_scale_factor() const; + private: - void append_data(void *data, uint64_t samples); + void append_data(void *data, uint64_t samples, uint16_t pitch); void free_envelop(); void reallocate_envelope(Envelope &l); void append_payload_to_envelope_levels(); @@ -102,8 +110,9 @@ private: private: - struct Envelope _envelope_levels[2*DS_MAX_ANALOG_PROBES_NUM][ScaleStepCount]; - + struct Envelope _envelope_levels[DS_MAX_ANALOG_PROBES_NUM][ScaleStepCount]; + uint8_t _unit_bytes; + uint16_t _unit_pitch; friend class AnalogSnapshotTest::Basic; }; diff --git a/DSView/pv/data/snapshot.cpp b/DSView/pv/data/snapshot.cpp index d49fac6e..46683579 100644 --- a/DSView/pv/data/snapshot.cpp +++ b/DSView/pv/data/snapshot.cpp @@ -93,6 +93,26 @@ uint64_t Snapshot::get_sample_count() const return _sample_count; } +uint64_t Snapshot::get_ring_start() const +{ + boost::lock_guard lock(_mutex); + if (_sample_count < _total_sample_count) + return 0; + else + return _ring_sample_count; +} + +uint64_t Snapshot::get_ring_end() const +{ + boost::lock_guard lock(_mutex); + if (_sample_count == 0) + return 0; + else if (_ring_sample_count == 0) + return _total_sample_count - 1; + else + return _ring_sample_count - 1; +} + const void* Snapshot::get_data() const { return _data; diff --git a/DSView/pv/data/snapshot.h b/DSView/pv/data/snapshot.h index a94e3e80..07d788f7 100644 --- a/DSView/pv/data/snapshot.h +++ b/DSView/pv/data/snapshot.h @@ -39,6 +39,8 @@ public: virtual void init() = 0; uint64_t get_sample_count() const; + uint64_t get_ring_start() const; + uint64_t get_ring_end() const; const void * get_data() const; diff --git a/DSView/pv/dialogs/calibration.cpp b/DSView/pv/dialogs/calibration.cpp old mode 100755 new mode 100644 index d8cca7f3..f3d231d3 --- a/DSView/pv/dialogs/calibration.cpp +++ b/DSView/pv/dialogs/calibration.cpp @@ -107,17 +107,17 @@ void Calibration::set_device(boost::shared_ptr dev_inst) uint64_t vgain = 0, vgain_default = 0; uint16_t vgain_range = 0; - GVariant* gvar = _dev_inst->get_config(probe, NULL, SR_CONF_VGAIN); + GVariant* gvar = _dev_inst->get_config(probe, NULL, SR_CONF_PROBE_VGAIN); if (gvar != NULL) { vgain = g_variant_get_uint64(gvar); g_variant_unref(gvar); } - gvar = _dev_inst->get_config(probe, NULL, SR_CONF_VGAIN_DEFAULT); + gvar = _dev_inst->get_config(probe, NULL, SR_CONF_PROBE_VGAIN_DEFAULT); if (gvar != NULL) { vgain_default = g_variant_get_uint64(gvar); g_variant_unref(gvar); } - gvar = _dev_inst->get_config(probe, NULL, SR_CONF_VGAIN_RANGE); + gvar = _dev_inst->get_config(probe, NULL, SR_CONF_PROBE_VGAIN_RANGE); if (gvar != NULL) { vgain_range = g_variant_get_uint16(gvar); g_variant_unref(gvar); @@ -135,12 +135,12 @@ void Calibration::set_device(boost::shared_ptr dev_inst) uint64_t voff = 0; uint16_t voff_range = 0; - gvar = _dev_inst->get_config(probe, NULL, SR_CONF_VOFF); + gvar = _dev_inst->get_config(probe, NULL, SR_CONF_PROBE_VOFF); if (gvar != NULL) { voff = g_variant_get_uint16(gvar); g_variant_unref(gvar); } - gvar = _dev_inst->get_config(probe, NULL, SR_CONF_VOFF_RANGE); + gvar = _dev_inst->get_config(probe, NULL, SR_CONF_PROBE_VOFF_RANGE); if (gvar != NULL) { voff_range = g_variant_get_uint16(gvar); g_variant_unref(gvar); @@ -185,16 +185,16 @@ void Calibration::set_value(int value) assert(probe); if (sc->objectName() == VGAIN+probe->index) { uint64_t vgain_default; - GVariant* gvar = _dev_inst->get_config(probe, NULL, SR_CONF_VGAIN_DEFAULT); + GVariant* gvar = _dev_inst->get_config(probe, NULL, SR_CONF_PROBE_VGAIN_DEFAULT); if (gvar != NULL) { vgain_default = g_variant_get_uint64(gvar); g_variant_unref(gvar); - _dev_inst->set_config(probe, NULL, SR_CONF_VGAIN, + _dev_inst->set_config(probe, NULL, SR_CONF_PROBE_VGAIN, g_variant_new_uint64(value+vgain_default)); } break; } else if (sc->objectName() == VOFF+probe->index) { - _dev_inst->set_config(probe, NULL, SR_CONF_VOFF, + _dev_inst->set_config(probe, NULL, SR_CONF_PROBE_VOFF, g_variant_new_uint16(value)); break; } @@ -262,17 +262,17 @@ void Calibration::reload_value() uint64_t vgain = 0, vgain_default = 0; uint16_t vgain_range = 0; - GVariant* gvar = _dev_inst->get_config(probe, NULL, SR_CONF_VGAIN); + GVariant* gvar = _dev_inst->get_config(probe, NULL, SR_CONF_PROBE_VGAIN); if (gvar != NULL) { vgain = g_variant_get_uint64(gvar); g_variant_unref(gvar); } - gvar = _dev_inst->get_config(probe, NULL, SR_CONF_VGAIN_DEFAULT); + gvar = _dev_inst->get_config(probe, NULL, SR_CONF_PROBE_VGAIN_DEFAULT); if (gvar != NULL) { vgain_default = g_variant_get_uint64(gvar); g_variant_unref(gvar); } - gvar = _dev_inst->get_config(probe, NULL, SR_CONF_VGAIN_RANGE); + gvar = _dev_inst->get_config(probe, NULL, SR_CONF_PROBE_VGAIN_RANGE); if (gvar != NULL) { vgain_range = g_variant_get_uint16(gvar); g_variant_unref(gvar); @@ -280,12 +280,12 @@ void Calibration::reload_value() uint64_t voff = 0; uint16_t voff_range = 0; - gvar = _dev_inst->get_config(probe, NULL, SR_CONF_VOFF); + gvar = _dev_inst->get_config(probe, NULL, SR_CONF_PROBE_VOFF); if (gvar != NULL) { voff = g_variant_get_uint16(gvar); g_variant_unref(gvar); } - gvar = _dev_inst->get_config(probe, NULL, SR_CONF_VOFF_RANGE); + gvar = _dev_inst->get_config(probe, NULL, SR_CONF_PROBE_VOFF_RANGE); if (gvar != NULL) { voff_range = g_variant_get_uint16(gvar); g_variant_unref(gvar); diff --git a/DSView/pv/dialogs/calibration.h b/DSView/pv/dialogs/calibration.h old mode 100755 new mode 100644 diff --git a/DSView/pv/dialogs/deviceoptions.cpp b/DSView/pv/dialogs/deviceoptions.cpp index a8471246..3a7844f8 100644 --- a/DSView/pv/dialogs/deviceoptions.cpp +++ b/DSView/pv/dialogs/deviceoptions.cpp @@ -24,8 +24,9 @@ #include -#include #include +#include +#include #include "dsmessagebox.h" #include @@ -47,20 +48,10 @@ DeviceOptions::DeviceOptions(QWidget *parent, boost::shared_ptrsetLayout(get_property_form(_props_box)); _layout.addWidget(_props_box); - if (_dev_inst->dev_inst()->mode != DSO) { - _probes_box = new QGroupBox(tr("Channels"), this); - setup_probes(); - _probes_box->setLayout(&_probes_box_layout); - _layout.addWidget(_probes_box); - } else if (_dev_inst->name().contains("DSCope")){ - _config_button = new QPushButton(tr("Auto Calibration"), this); - _layout.addWidget(_config_button); - connect(_config_button, SIGNAL(clicked()), this, SLOT(zero_adj())); - - _cali_button = new QPushButton(tr("Manual Calibration"), this); - _layout.addWidget(_cali_button); - connect(_cali_button, SIGNAL(clicked()), this, SLOT(on_calibration())); - } + QGroupBox *dynamic_box = new QGroupBox(dynamic_widget(_dynamic_layout), + this); + dynamic_box->setLayout(&_dynamic_layout); + _layout.addWidget(dynamic_box); _layout.addStretch(1); _layout.addWidget(&_button_box); @@ -88,20 +79,21 @@ void DeviceOptions::accept() bool hasEnabled = false; // Commit the properties - const vector< boost::shared_ptr > &properties = + const vector< boost::shared_ptr > &dev_props = _device_options_binding.properties(); - BOOST_FOREACH(boost::shared_ptr p, properties) { + BOOST_FOREACH(boost::shared_ptr p, dev_props) { assert(p); p->commit(); } // Commit the probes - if (_dev_inst->dev_inst()->mode != DSO) { + if (_dev_inst->dev_inst()->mode == LOGIC || + _dev_inst->dev_inst()->mode == ANALOG) { int index = 0; for (const GSList *l = _dev_inst->dev_inst()->channels; l; l = l->next) { sr_channel *const probe = (sr_channel*)l->data; assert(probe); - probe->enabled = (_probes_checkBox_list.at(index)->checkState() == Qt::Checked); + probe->enabled = _probes_checkBox_list.at(index)->isChecked(); index++; if (probe->enabled) hasEnabled = true; @@ -111,6 +103,17 @@ void DeviceOptions::accept() } if (hasEnabled) { + QVector::iterator i = _probe_options_binding_list.begin(); + while(i != _probe_options_binding_list.end()) { + const vector< boost::shared_ptr > &probe_props = + (*i)->properties(); + BOOST_FOREACH(boost::shared_ptr p, probe_props) { + assert(p); + p->commit(); + } + i++; + } + QDialog::accept(); } else { dialogs::DSMessageBox msg(this); @@ -152,7 +155,7 @@ QGridLayout * DeviceOptions::get_property_form(QWidget * parent) return layout; } -void DeviceOptions::setup_probes() +void DeviceOptions::logic_probes(QGridLayout &layout) { using namespace Qt; @@ -162,11 +165,11 @@ void DeviceOptions::setup_probes() int vld_ch_num = 0; int cur_ch_num = 0; - while(_probes_box_layout.count() > 0) + while(layout.count() > 0) { //remove Widgets in QLayoutGrid - QWidget* widget = _probes_box_layout.itemAt(0)->widget(); - _probes_box_layout.removeWidget(widget); + QWidget* widget = layout.itemAt(0)->widget(); + layout.removeWidget(widget); delete widget; } _probes_label_list.clear(); @@ -185,7 +188,7 @@ void DeviceOptions::setup_probes() for (unsigned int i=0; iindex), this); QCheckBox *probe_checkBox = new QCheckBox(this); probe_checkBox->setCheckState(probe->enabled ? Qt::Checked : Qt::Unchecked); - _probes_box_layout.addWidget(probe_label, row1 * 2 + row0, col); - _probes_box_layout.addWidget(probe_checkBox, row1 * 2 + 1 + row0, col); + layout.addWidget(probe_label, row1 * 2 + row0, col); + layout.addWidget(probe_checkBox, row1 * 2 + 1 + row0, col); _probes_label_list.push_back(probe_label); _probes_checkBox_list.push_back(probe_checkBox); @@ -235,8 +238,8 @@ void DeviceOptions::setup_probes() connect(_disable_all_probes, SIGNAL(clicked()), this, SLOT(disable_all_probes())); - _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); + layout.addWidget(_enable_all_probes, (row1 + 1) * 2 + row0, 0, 1, 4); + layout.addWidget(_disable_all_probes, (row1 + 1) * 2 + row0, 4, 1, 4); } void DeviceOptions::set_all_probes(bool set) @@ -329,7 +332,7 @@ void DeviceOptions::mode_check() g_variant_unref(gvar); if (mode != _mode) { - setup_probes(); + dynamic_widget(_dynamic_layout); _mode = mode; } } @@ -355,49 +358,150 @@ 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().toUtf8().data())); - setup_probes(); + dynamic_widget(_dynamic_layout); } void DeviceOptions::channel_enable() { - QCheckBox* sc=dynamic_cast(sender()); - if (sc == NULL || !sc->isChecked()) - return; + if (_dev_inst->dev_inst()->mode == LOGIC) { + QCheckBox* sc=dynamic_cast(sender()); + if (sc == NULL || !sc->isChecked()) + return; - GVariant* gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_STREAM); - if (gvar == NULL) - return; + GVariant* gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_STREAM); + if (gvar == NULL) + return; - bool stream_mode = g_variant_get_boolean(gvar); - g_variant_unref(gvar); + bool stream_mode = g_variant_get_boolean(gvar); + g_variant_unref(gvar); - if (!stream_mode) - return; + if (!stream_mode) + return; - int cur_ch_num = 0; - QVector::iterator i = _probes_checkBox_list.begin(); - while(i != _probes_checkBox_list.end()) { - if ((*i)->isChecked()) - cur_ch_num++; - i++; + int cur_ch_num = 0; + QVector::iterator i = _probes_checkBox_list.begin(); + while(i != _probes_checkBox_list.end()) { + if ((*i)->isChecked()) + cur_ch_num++; + i++; + } + + gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_VLD_CH_NUM); + if (gvar == NULL) + return; + + int vld_ch_num = g_variant_get_int16(gvar); + g_variant_unref(gvar); + if (cur_ch_num > vld_ch_num) { + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Information")); + msg.mBox()->setInformativeText(tr("Current mode only suppport max ") + QString::number(vld_ch_num) + tr(" channels!")); + msg.mBox()->addButton(tr("Ok"), QMessageBox::AcceptRole); + msg.mBox()->setIcon(QMessageBox::Information); + msg.exec(); + + sc->setChecked(false); + } + } else if (_dev_inst->dev_inst()->mode == ANALOG) { + QCheckBox* sc=dynamic_cast(sender()); + if (sc != NULL) { + QGridLayout *const layout = (QGridLayout *)sc->property("Layout").value(); + int i = layout->count(); + while(i--) + { + QWidget* w = layout->itemAt(i)->widget(); + if (w->property("Enable").isNull()) { + w->setEnabled(sc->isChecked()); + } + } + //dynamic_widget(_dynamic_layout); + } + } +} + +QString DeviceOptions::dynamic_widget(QGridLayout& inner_layout) { + if (_dev_inst->dev_inst()->mode == LOGIC) { + logic_probes(inner_layout); + return tr("Channels"); + } else if (_dev_inst->dev_inst()->mode == DSO) { + _config_button = new QPushButton(tr("Auto Calibration"), this); + inner_layout.addWidget(_config_button, 0, 0, 1, 1); + connect(_config_button, SIGNAL(clicked()), this, SLOT(zero_adj())); + _cali_button = new QPushButton(tr("Manual Calibration"), this); + inner_layout.addWidget(_cali_button, 1, 0, 1, 1); + connect(_cali_button, SIGNAL(clicked()), this, SLOT(on_calibration())); + + return tr("Calibration"); + } else if (_dev_inst->dev_inst()->mode == ANALOG) { + analog_probes(inner_layout); + return tr("Channels"); + } else { + return tr("Undefined"); + } +} + +void DeviceOptions::analog_probes(QGridLayout &layout) +{ + using namespace Qt; + + while(layout.count() > 0) + { + //remove Widgets in QLayoutGrid + QWidget* widget = layout.itemAt(0)->widget(); + layout.removeWidget(widget); + delete widget; + } + _probe_widget_list.clear(); + _probes_checkBox_list.clear(); + _probe_options_binding_list.clear(); + + QTabWidget *tabWidget = new QTabWidget(this); + tabWidget->setTabPosition(QTabWidget::North); + tabWidget->setUsesScrollButtons(false); + for (const GSList *l = _dev_inst->dev_inst()->channels; l; l = l->next) { + sr_channel *const probe = (sr_channel*)l->data; + assert(probe); + + QWidget *probe_widget = new QWidget(tabWidget); + QGridLayout *probe_layout = new QGridLayout(probe_widget); + probe_widget->setLayout(probe_layout); + _probe_widget_list.push_back(probe_widget); + + QCheckBox *probe_checkBox = new QCheckBox(this); + QVariant vlayout = QVariant::fromValue((void *)probe_layout); + probe_checkBox->setProperty("Layout", vlayout); + probe_checkBox->setProperty("Enable", true); + probe_checkBox->setCheckState(probe->enabled ? Qt::Checked : Qt::Unchecked); + _probes_checkBox_list.push_back(probe_checkBox); + + QLabel *en_label = new QLabel(tr("Enable: "), this); + en_label->setProperty("Enable", true); + probe_layout->addWidget(en_label, 0, 0, 1, 1); + probe_layout->addWidget(probe_checkBox, 0, 1, 1, 3); + + + pv::prop::binding::ProbeOptions *probe_options_binding = + new pv::prop::binding::ProbeOptions(_dev_inst->dev_inst(), probe); + const vector< boost::shared_ptr > &properties = + probe_options_binding->properties(); + int i = 1; + BOOST_FOREACH(boost::shared_ptr p, properties) + { + assert(p); + probe_layout->addWidget(new QLabel(p->name(), probe_widget), i, 0, 1, 1); + QWidget *pow = p->get_widget(probe_widget); + pow->setEnabled(probe_checkBox->isChecked()); + probe_layout->addWidget(pow, i, 1, 1, 3); + i++; + } + _probe_options_binding_list.push_back(probe_options_binding); + + connect(probe_checkBox, SIGNAL(released()), this, SLOT(channel_enable())); + + tabWidget->addTab(probe_widget, QString::fromUtf8(probe->name)); } - gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_VLD_CH_NUM); - if (gvar == NULL) - return; - - int vld_ch_num = g_variant_get_int16(gvar); - g_variant_unref(gvar); - if (cur_ch_num > vld_ch_num) { - dialogs::DSMessageBox msg(this); - msg.mBox()->setText(tr("Information")); - msg.mBox()->setInformativeText(tr("Current mode only suppport max ") + QString::number(vld_ch_num) + tr(" channels!")); - msg.mBox()->addButton(tr("Ok"), QMessageBox::AcceptRole); - msg.mBox()->setIcon(QMessageBox::Information); - msg.exec(); - - sc->setChecked(false); - } + layout.addWidget(tabWidget, 0, 0, 1, 1); } } // namespace dialogs diff --git a/DSView/pv/dialogs/deviceoptions.h b/DSView/pv/dialogs/deviceoptions.h index 8c41aa59..168eafa9 100644 --- a/DSView/pv/dialogs/deviceoptions.h +++ b/DSView/pv/dialogs/deviceoptions.h @@ -43,6 +43,7 @@ #include #include "../device/devinst.h" #include "../prop/binding/deviceoptions.h" +#include "../prop/binding/probeoptions.h" #include "../toolbars/titlebar.h" #include "../dialogs/dsdialog.h" @@ -64,7 +65,9 @@ private: QGridLayout *get_property_form(QWidget *parent); - void setup_probes(); + void logic_probes(QGridLayout& layout); + void analog_probes(QGridLayout& layout); + QString dynamic_widget(QGridLayout &_dynamic_layout); void set_all_probes(bool set); void enable_max_probes(); @@ -83,10 +86,10 @@ private: QVBoxLayout _layout; toolbars::TitleBar *_titlebar; - QGroupBox *_probes_box; - QGridLayout _probes_box_layout; + QGridLayout _dynamic_layout; QVector _probes_label_list; QVector _probes_checkBox_list; + QVector _probe_widget_list; QGroupBox *_props_box; @@ -98,6 +101,7 @@ private: QString _mode; pv::prop::binding::DeviceOptions _device_options_binding; + QVector _probe_options_binding_list; }; } // namespace dialogs diff --git a/DSView/pv/dialogs/dsdialog.cpp b/DSView/pv/dialogs/dsdialog.cpp old mode 100755 new mode 100644 diff --git a/DSView/pv/dialogs/dsdialog.h b/DSView/pv/dialogs/dsdialog.h old mode 100755 new mode 100644 diff --git a/DSView/pv/dialogs/dsmessagebox.cpp b/DSView/pv/dialogs/dsmessagebox.cpp old mode 100755 new mode 100644 diff --git a/DSView/pv/dialogs/dsmessagebox.h b/DSView/pv/dialogs/dsmessagebox.h old mode 100755 new mode 100644 diff --git a/DSView/pv/dialogs/interval.cpp b/DSView/pv/dialogs/interval.cpp old mode 100755 new mode 100644 diff --git a/DSView/pv/dialogs/interval.h b/DSView/pv/dialogs/interval.h old mode 100755 new mode 100644 diff --git a/DSView/pv/dialogs/shadow.cpp b/DSView/pv/dialogs/shadow.cpp old mode 100755 new mode 100644 diff --git a/DSView/pv/dialogs/shadow.h b/DSView/pv/dialogs/shadow.h old mode 100755 new mode 100644 diff --git a/DSView/pv/mainwindow.cpp b/DSView/pv/mainwindow.cpp index 422ddee1..e6c4e4a1 100644 --- a/DSView/pv/mainwindow.cpp +++ b/DSView/pv/mainwindow.cpp @@ -75,6 +75,7 @@ #include "view/signal.h" #include "view/dsosignal.h" #include "view/logicsignal.h" +#include "view/analogsignal.h" /* __STDC_FORMAT_MACROS is required for PRIu64 and friends (in C++). */ #define __STDC_FORMAT_MACROS @@ -450,11 +451,11 @@ void MainWindow::run_stop() switch(_session.get_capture_state()) { case SigSession::Init: case SigSession::Stopped: - _view->capture_init(false); commit_trigger(false); _session.start_capture(false, boost::bind(&MainWindow::session_error, this, QString(tr("Capture failed")), _1)); + _view->capture_init(false); break; case SigSession::Running: @@ -468,11 +469,11 @@ void MainWindow::instant_stop() switch(_session.get_capture_state()) { case SigSession::Init: case SigSession::Stopped: - _view->capture_init(true); commit_trigger(true); _session.start_capture(true, boost::bind(&MainWindow::session_error, this, QString(tr("Capture failed")), _1)); + _view->capture_init(true); break; case SigSession::Running: @@ -767,13 +768,14 @@ bool MainWindow::load_session(QString name) (probe->type == obj["type"].toDouble())) { isEnabled = true; probe->enabled = obj["enabled"].toBool(); - //probe->colour = obj["colour"].toString(); probe->name = g_strdup(obj["name"].toString().toStdString().c_str()); probe->vdiv = obj["vdiv"].toDouble(); probe->coupling = obj["coupling"].toDouble(); probe->vfactor = obj["vfactor"].toDouble(); probe->trig_value = obj["trigValue"].toDouble(); - //probe->zeroPos = obj["zeroPos"].toDouble(); + probe->map_unit = g_strdup(obj["mapUnit"].toString().toStdString().c_str()); + probe->map_min = obj["mapMin"].toDouble(); + probe->map_max = obj["mapMax"].toDouble(); break; } } @@ -807,6 +809,13 @@ bool MainWindow::load_session(QString name) dsoSig->set_trig_vrate(obj["trigValue"].toDouble()); dsoSig->commit_settings(); } + + boost::shared_ptr analogSig; + if (analogSig = dynamic_pointer_cast(s)) { + analogSig->set_zero_vrate(obj["zeroPos"].toDouble(), true); + analogSig->commit_settings(); + } + break; } } @@ -900,6 +909,16 @@ bool MainWindow::store_session(QString name) s_obj["trigValue"] = dsoSig->get_trig_vrate(); s_obj["zeroPos"] = dsoSig->get_zero_vrate(); } + + boost::shared_ptr analogSig; + if (analogSig = dynamic_pointer_cast(s)) { + s_obj["vdiv"] = QJsonValue::fromVariant(static_cast(analogSig->get_vdiv())); + s_obj["coupling"] = analogSig->get_acCoupling(); + s_obj["zeroPos"] = analogSig->get_zero_vrate(); + s_obj["mapUnit"] = analogSig->get_mapUnit(); + s_obj["mapMin"] = analogSig->get_mapMin(); + s_obj["mapMax"] = analogSig->get_mapMax(); + } channelVar.append(s_obj); } sessionVar["channel"] = channelVar; diff --git a/DSView/pv/prop/binding/deviceoptions.cpp b/DSView/pv/prop/binding/deviceoptions.cpp index 9e7e2585..382d51a5 100644 --- a/DSView/pv/prop/binding/deviceoptions.cpp +++ b/DSView/pv/prop/binding/deviceoptions.cpp @@ -84,8 +84,8 @@ DeviceOptions::DeviceOptions(struct sr_dev_inst *sdi) : case SR_CONF_FILTER: case SR_CONF_MAX_HEIGHT: case SR_CONF_MAX_HEIGHT_VALUE: - case SR_CONF_COUPLING: - case SR_CONF_EN_CH: + case SR_CONF_PROBE_COUPLING: + case SR_CONF_PROBE_EN: case SR_CONF_OPERATION_MODE: case SR_CONF_BUFFER_OPTIONS: case SR_CONF_THRESHOLD: @@ -93,7 +93,7 @@ DeviceOptions::DeviceOptions(struct sr_dev_inst *sdi) : case SR_CONF_STREAM: case SR_CONF_TEST: case SR_CONF_STATUS: - case SR_CONF_FACTOR: + case SR_CONF_PROBE_FACTOR: bind_enum(name, key, gvar_list); break; @@ -116,7 +116,7 @@ DeviceOptions::DeviceOptions(struct sr_dev_inst *sdi) : bind_enum(name, key, gvar_list, print_timebase); break; - case SR_CONF_VDIV: + case SR_CONF_PROBE_VDIV: bind_enum(name, key, gvar_list, print_vdiv); break; default: diff --git a/DSView/pv/prop/binding/probeoptions.cpp b/DSView/pv/prop/binding/probeoptions.cpp new file mode 100644 index 00000000..39c12d61 --- /dev/null +++ b/DSView/pv/prop/binding/probeoptions.cpp @@ -0,0 +1,247 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2018 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include + +#include + +#include "probeoptions.h" + +#include +#include +#include +#include + +using namespace boost; +using namespace std; + +namespace pv { +namespace prop { +namespace binding { + +ProbeOptions::ProbeOptions(struct sr_dev_inst *sdi, + struct sr_channel *probe) : + _sdi(sdi), + _probe(probe) +{ + GVariant *gvar_opts, *gvar_list; + gsize num_opts; + + if ((sr_config_list(sdi->driver, sdi, NULL, SR_CONF_PROBE_CONFIGS, + &gvar_opts) != SR_OK)) + /* Driver supports no device instance options. */ + return; + + const int *const options = (const int32_t *)g_variant_get_fixed_array( + gvar_opts, &num_opts, sizeof(int32_t)); + for (unsigned int i = 0; i < num_opts; i++) { + const struct sr_config_info *const info = + sr_config_info_get(options[i]); + + if (!info) + continue; + + const int key = info->key; + + if(sr_config_list(_sdi->driver, _sdi, NULL, key, &gvar_list) != SR_OK) + gvar_list = NULL; + + const QString name(info->label); + + switch(key) + { + case SR_CONF_PROBE_VDIV: + bind_vdiv(name, gvar_list); + break; + + case SR_CONF_PROBE_MAP_MIN: + case SR_CONF_PROBE_MAP_MAX: + bind_double(name, key, "", + pair(-999999.99, 999999.99), 2, 0.01); + break; + + case SR_CONF_PROBE_COUPLING: + bind_coupling(name, gvar_list); + break; + + case SR_CONF_PROBE_MAP_UNIT: + bind_enum(name, key, gvar_list); + break; + + default: + gvar_list = NULL; + } + + if (gvar_list) + g_variant_unref(gvar_list); + } + g_variant_unref(gvar_opts); +} + +GVariant* ProbeOptions::config_getter( + const struct sr_dev_inst *sdi, + const struct sr_channel *probe, int key) +{ + GVariant *data = NULL; + if (sr_config_get(sdi->driver, sdi, probe, NULL, key, &data) != SR_OK) { + qDebug() << + "WARNING: Failed to get value of config id" << key; + return NULL; + } + return data; +} + +void ProbeOptions::config_setter( + struct sr_dev_inst *sdi, + struct sr_channel *probe, int key, GVariant* value) +{ + if (sr_config_set(sdi, probe, NULL, key, value) != SR_OK) + qDebug() << "WARNING: Failed to set value of sample rate"; +} + +void ProbeOptions::bind_bool(const QString &name, int key) +{ + _properties.push_back(boost::shared_ptr( + new Bool(name, bind(config_getter, _sdi, _probe, key), + bind(config_setter, _sdi, _probe, key, _1)))); +} + +void ProbeOptions::bind_enum(const QString &name, int key, + GVariant *const gvar_list, boost::function printer) +{ + GVariant *gvar; + GVariantIter iter; + vector< pair > values; + + assert(gvar_list); + + g_variant_iter_init (&iter, gvar_list); + while ((gvar = g_variant_iter_next_value (&iter))) + values.push_back(make_pair(gvar, printer(gvar))); + + _properties.push_back(boost::shared_ptr( + new Enum(name, values, + bind(config_getter, _sdi, _probe, key), + bind(config_setter, _sdi, _probe, key, _1)))); +} + +void ProbeOptions::bind_int(const QString &name, int key, QString suffix, + optional< std::pair > range) +{ + _properties.push_back(boost::shared_ptr( + new Int(name, suffix, range, + bind(config_getter, _sdi, _probe, key), + bind(config_setter, _sdi, _probe, key, _1)))); +} + +void ProbeOptions::bind_double(const QString &name, int key, QString suffix, + optional< std::pair > range, + int decimals, boost::optional step) +{ + _properties.push_back(boost::shared_ptr( + new Double(name, decimals, suffix, range, step, + bind(config_getter, _sdi, _probe, key), + bind(config_setter, _sdi, _probe, key, _1)))); +} + +void ProbeOptions::bind_vdiv(const QString &name, + GVariant *const gvar_list) +{ + GVariant *gvar_list_vdivs; + + assert(gvar_list); + + if ((gvar_list_vdivs = g_variant_lookup_value(gvar_list, + "vdivs", G_VARIANT_TYPE("at")))) + { + bind_enum(name, SR_CONF_PROBE_VDIV, + gvar_list_vdivs, print_vdiv); + g_variant_unref(gvar_list_vdivs); + } +} + +void ProbeOptions::bind_coupling(const QString &name, + GVariant *const gvar_list) +{ + GVariant *gvar_list_coupling; + + assert(gvar_list); + + if ((gvar_list_coupling = g_variant_lookup_value(gvar_list, + "coupling", G_VARIANT_TYPE("ay")))) + { + bind_enum(name, SR_CONF_PROBE_COUPLING, + gvar_list_coupling, print_coupling); + g_variant_unref(gvar_list_coupling); + } +} + +QString ProbeOptions::print_gvariant(GVariant *const gvar) +{ + QString s; + + if (g_variant_is_of_type(gvar, G_VARIANT_TYPE("s"))) + s = QString::fromUtf8(g_variant_get_string(gvar, NULL)); + else + { + gchar *const text = g_variant_print(gvar, FALSE); + s = QString::fromUtf8(text); + g_free(text); + } + + return s; +} + +QString ProbeOptions::print_vdiv(GVariant *const gvar) +{ + uint64_t p, q; + g_variant_get(gvar, "t", &p); + if (p < 1000ULL) { + q = 1000; + } else if (p < 1000000ULL) { + q = 1; + p /= 1000; + } + return QString(sr_voltage_string(p, q)); +} + +QString ProbeOptions::print_coupling(GVariant *const gvar) +{ + uint8_t coupling; + g_variant_get(gvar, "y", &coupling); + if (coupling == SR_DC_COUPLING) { + return QString("DC"); + } else if (coupling == SR_AC_COUPLING) { + return QString("AC"); + } else if (coupling == SR_GND_COUPLING) { + return QString("GND"); + } else { + return QString("Undefined"); + } +} + +} // binding +} // prop +} // pv + diff --git a/DSView/pv/prop/binding/probeoptions.h b/DSView/pv/prop/binding/probeoptions.h new file mode 100644 index 00000000..0bae7efe --- /dev/null +++ b/DSView/pv/prop/binding/probeoptions.h @@ -0,0 +1,83 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2018 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#ifndef DSVIEW_PV_PROP_BINDING_PROBEOPTIONS_H +#define DSVIEW_PV_PROP_BINDING_PROBEOPTIONS_H + +#include +#include + +#include + +#include +#include "binding.h" + +namespace pv { +namespace prop { +namespace binding { + +class ProbeOptions : public Binding +{ +public: + ProbeOptions(struct sr_dev_inst *sdi, + struct sr_channel *probe); + +private: + + static GVariant* config_getter( + const struct sr_dev_inst *sdi, + const struct sr_channel *probe, int key); + static void config_setter( + struct sr_dev_inst *sdi, + struct sr_channel *probe, int key, GVariant* value); + + void bind_bool(const QString &name, int key); + void bind_enum(const QString &name, int key, + GVariant *const gvar_list, + boost::function printer = print_gvariant); + void bind_int(const QString &name, int key, QString suffix, + boost::optional< std::pair > range); + + void bind_double(const QString &name, int key, QString suffix, + boost::optional > range, + int decimals, boost::optional step); + + static QString print_gvariant(GVariant *const gvar); + + void bind_vdiv(const QString &name, + GVariant *const gvar_list); + void bind_coupling(const QString &name, + GVariant *const gvar_list); + + static QString print_vdiv(GVariant *const gvar); + static QString print_coupling(GVariant *const gvar); + +protected: + struct sr_dev_inst *const _sdi; + struct sr_channel *const _probe; +}; + +} // binding +} // prop +} // pv + +#endif // DSVIEW_PV_PROP_BINDING_DEVICEOPTIONS_H diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp index e33bcdb6..67f4eccf 100644 --- a/DSView/pv/sigsession.cpp +++ b/DSView/pv/sigsession.cpp @@ -172,10 +172,11 @@ void SigSession::set_device(boost::shared_ptr dev_inst) throw(Q _cur_samplerate = _dev_inst->get_sample_rate(); _cur_samplelimits = _dev_inst->get_sample_limit(); - if (_dev_inst->dev_inst()->mode == DSO) - set_run_mode(Repetitive); - else - set_run_mode(Single); +// if (_dev_inst->dev_inst()->mode == DSO) +// set_run_mode(Repetitive); +// else +// set_run_mode(Single); + set_run_mode(Single); } catch(const QString e) { throw(e); return; @@ -340,6 +341,10 @@ void SigSession::capture_init() if (dsoSig = dynamic_pointer_cast(s)) { dsoSig->set_zero_vrate(dsoSig->get_zero_vrate(), true); } + boost::shared_ptr analogSig; + if (analogSig = dynamic_pointer_cast(s)) { + analogSig->set_zero_vrate(analogSig->get_zero_vrate(), true); + } } } @@ -750,11 +755,24 @@ void SigSession::reload() // new view::DsoSignal(_dev_inst,_dso_data, probe)); // break; -// case SR_CHANNEL_ANALOG: -// if (probe->enabled) -// signal = boost::shared_ptr( -// new view::AnalogSignal(_dev_inst, _analog_data, probe)); -// break; + case SR_CHANNEL_ANALOG: + if (probe->enabled) { + std::vector< boost::shared_ptr >::iterator i = _signals.begin(); + while (i != _signals.end()) { + if ((*i)->get_index() == probe->index) { + boost::shared_ptr analogSig; + if (analogSig = dynamic_pointer_cast(*i)) + signal = boost::shared_ptr( + new view::AnalogSignal(analogSig, _analog_data, probe)); + break; + } + i++; + } + if (!signal.get()) + signal = boost::shared_ptr( + new view::AnalogSignal(_dev_inst, _analog_data, probe)); + } + break; } if (signal.get()) sigs.push_back(signal); @@ -1521,7 +1539,7 @@ bool SigSession::repeat_check() QTimer::singleShot(_repeat_intvl*1000/RepeatHoldDiv, this, SLOT(repeat_update())); return true; } else { - return true; + return false; } } diff --git a/DSView/pv/sigsession.h b/DSView/pv/sigsession.h index 609efe9e..9c4b5983 100644 --- a/DSView/pv/sigsession.h +++ b/DSView/pv/sigsession.h @@ -96,7 +96,7 @@ private: static const int RepeatHoldDiv = 20; public: - static const int ViewTime = 50; + static const int ViewTime = 100; static const int WaitShowTime = 500; public: diff --git a/DSView/pv/storesession.cpp b/DSView/pv/storesession.cpp index 5885bd49..8518fd58 100644 --- a/DSView/pv/storesession.cpp +++ b/DSView/pv/storesession.cpp @@ -318,7 +318,7 @@ QString StoreSession::meta_gen(boost::shared_ptr snapshot) fprintf(meta, "hDiv = %" PRIu64 "\n", tmp_u64); g_variant_unref(gvar); } - gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_DSO_BITS); + gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_UNIT_BITS); if (gvar != NULL) { uint8_t tmp_u8 = g_variant_get_byte(gvar); fprintf(meta, "bits = %d\n", tmp_u8); diff --git a/DSView/pv/toolbars/samplingbar.cpp b/DSView/pv/toolbars/samplingbar.cpp index 0e84016c..be008b43 100644 --- a/DSView/pv/toolbars/samplingbar.cpp +++ b/DSView/pv/toolbars/samplingbar.cpp @@ -529,7 +529,7 @@ void SamplingBar::on_samplecount_sel(int index) boost::shared_ptr _devInst = get_selected_device(); assert(_devInst); - if (_devInst->name() == "DSLogic" && _devInst->dev_inst()->mode != DSO) { + if (_devInst->dev_inst()->mode != DSO) { // Set the sample count _devInst->set_config(NULL, NULL, @@ -554,7 +554,7 @@ void SamplingBar::on_samplerate_sel(int index) // Get last samplerate //last_sample_rate = get_selected_device()->get_sample_rate(); - if (dev_inst->name() == "DSLogic" && dev_inst->dev_inst()->mode != DSO) { + if (dev_inst->dev_inst()->mode != DSO) { // Set the samplerate get_selected_device()->set_config(NULL, NULL, SR_CONF_SAMPLERATE, diff --git a/DSView/pv/view/analogsignal.cpp b/DSView/pv/view/analogsignal.cpp index 83d079ab..6172fd81 100644 --- a/DSView/pv/view/analogsignal.cpp +++ b/DSView/pv/view/analogsignal.cpp @@ -24,45 +24,63 @@ #include -#include "analogsignal.h" -#include "pv/data/analog.h" -#include "pv/data/analogsnapshot.h" -#include "view.h" +#include "../view/analogsignal.h" +#include "../data/analog.h" +#include "../data/analogsnapshot.h" +#include "../view/view.h" +#include "../device/devinst.h" using namespace boost; using namespace std; +#define byte(x) uint##x##_t + namespace pv { namespace view { -//const QColor AnalogSignal::SignalColours[4] = { -// QColor(0xC4, 0xA0, 0x00), // Yellow -// QColor(0x87, 0x20, 0x7A), // Magenta -// QColor(0x20, 0x4A, 0x87), // Blue -// QColor(0x4E, 0x9A, 0x06) // Green -//}; const QColor AnalogSignal::SignalColours[4] = { - QColor(17, 133, 209, 255), // dsBlue QColor(238, 178, 17, 255), // dsYellow + QColor(0, 153, 37, 255), // dsGreen QColor(213, 15, 37, 255), // dsRed - QColor(0, 153, 37, 255) // dsGreen + QColor(17, 133, 209, 255) // dsBlue }; -const float AnalogSignal::EnvelopeThreshold = 256.0f; +const float AnalogSignal::EnvelopeThreshold = 16.0f; AnalogSignal::AnalogSignal(boost::shared_ptr dev_inst, boost::shared_ptr data, sr_channel *probe) : Signal(dev_inst, probe), - _data(data) + _data(data), + _rects(NULL) { _typeWidth = 3; _colour = SignalColours[probe->index % countof(SignalColours)]; - _scale = _totalHeight * 1.0f / 65536; + _bits = -1; + _zero_vrate = 0.5; +} + +AnalogSignal::AnalogSignal(boost::shared_ptr s, + boost::shared_ptr data, + sr_channel *probe) : + Signal(*s.get(), probe), + _data(data), + _rects(NULL) +{ + _typeWidth = 3; + _bits = s->get_bits(); + _zero_vrate = s->get_zero_vrate(); + + _scale = s->get_scale(); + _hw_offset = s->get_hw_offset(); } AnalogSignal::~AnalogSignal() { + if (_rects) { + delete[] _rects; + _rects = NULL; + } } boost::shared_ptr AnalogSignal::data() const @@ -75,25 +93,236 @@ void AnalogSignal::set_scale(float scale) _scale = scale; } +float AnalogSignal::get_scale() const +{ + return _scale; +} + +int AnalogSignal::get_bits() const +{ + return _bits; +} + +int AnalogSignal::get_hw_offset() const +{ + return _hw_offset; +} + +int AnalogSignal::commit_settings() +{ + int ret; + + // -- vdiv + ret = _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_VDIV, + g_variant_new_uint64(_probe->vdiv)); + + // -- coupling + ret = _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_COUPLING, + g_variant_new_byte(_probe->coupling)); + + // -- vpos + ret = _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_VPOS, + g_variant_new_double(_probe->vpos)); + + // -- trig_value + _dev_inst->set_config(_probe, NULL, SR_CONF_TRIGGER_VALUE, + g_variant_new_byte(_probe->trig_value)); + + return ret; +} + +/** + * Probe options + **/ +uint64_t AnalogSignal::get_vdiv() const +{ + uint64_t vdiv = 0; + GVariant* gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_PROBE_VDIV); + if (gvar != NULL) { + vdiv = g_variant_get_uint64(gvar); + g_variant_unref(gvar); + } + return vdiv; +} + +uint8_t AnalogSignal::get_acCoupling() const +{ + uint64_t coupling = 0; + GVariant* gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_PROBE_COUPLING); + if (gvar != NULL) { + coupling = g_variant_get_byte(gvar); + g_variant_unref(gvar); + } + return coupling; +} + +QString AnalogSignal::get_mapUnit() const +{ + QString unit; + GVariant* gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_PROBE_MAP_UNIT); + if (gvar != NULL) { + unit = g_variant_get_string(gvar, NULL); + g_variant_unref(gvar); + } + return unit; +} + +double AnalogSignal::get_mapMin() const +{ + double min; + GVariant* gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_PROBE_MAP_MIN); + if (gvar != NULL) { + min = g_variant_get_double(gvar); + g_variant_unref(gvar); + } + return min; +} + +double AnalogSignal::get_mapMax() const +{ + double max; + GVariant* gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_PROBE_MAP_MAX); + if (gvar != NULL) { + max = g_variant_get_double(gvar); + g_variant_unref(gvar); + } + return max; +} + +/** + * + **/ +void AnalogSignal::set_zero_vpos(int pos) +{ + if (enabled()) { + const int height = get_totalHeight(); + const int bottom = get_y() + height / 2; + set_zero_vrate(min(max(bottom - pos, 0), height) * 1.0 / height, false); + } +} + +int AnalogSignal::get_zero_vpos() const +{ + return (0.5 - _zero_vrate) * get_totalHeight() + get_y(); +} + +void AnalogSignal::set_zero_vrate(double rate, bool force_update) +{ + if (_view->session().get_capture_state() == SigSession::Running) + return; + + _zero_vrate = rate; + update_vpos(); + + if (force_update) + update_offset(); +} + +double AnalogSignal::get_zero_vrate() const +{ + return _zero_vrate; +} + +void AnalogSignal::update_vpos() +{ + double vpos_off = (0.5 - _zero_vrate) * get_vdiv() * DS_CONF_DSO_VDIVS; + _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_VPOS, + g_variant_new_double(vpos_off)); +} + +void AnalogSignal::update_offset() +{ + if (_dev_inst->name().contains("virtual") || + _dev_inst->name() == "DSLogic") + _hw_offset = (1 << _bits) * 0.5; + else + _hw_offset = _zero_vrate * ((1 << _bits) - 1); +} +/** + * Event + **/ +void AnalogSignal::resize() +{ + if (_rects) { + delete[] _rects; + _rects = NULL; + } +} + +/** + * Paint + **/ +void AnalogSignal::paint_back(QPainter &p, int left, int right) +{ + assert(_view); + + int i, j; + const double height = get_totalHeight(); + const int DIVS = DS_CONF_DSO_VDIVS; + const int minDIVS = 5; + const double STEPS = height / (DIVS * minDIVS); + const double mapSteps = (get_mapMax() - get_mapMin()) / DIVS; + const QString mapUnit = get_mapUnit(); + + QPen solidPen(Signal::dsFore); + solidPen.setStyle(Qt::SolidLine); + p.setPen(solidPen); + p.setBrush(Trace::dsBack); + + // paint rule + double y = get_y() - height * 0.5; + double mapValue = get_mapMax() + (0.5 - _zero_vrate) * (get_mapMax() - get_mapMin()); + for (i = 0; i < DIVS; i++) { + p.drawLine(left, y, left+10, y); + if (i == 0 || i == DIVS/2) + p.drawText(QRectF(left+15, y-10, 100, 20), + Qt::AlignLeft | Qt::AlignVCenter, + QString::number(mapValue,'f',2)+mapUnit); + p.drawLine(right, y, right-10, y); + if (i == 0 || i == DIVS/2) + p.drawText(QRectF(right-115, y-10, 100, 20), + Qt::AlignRight | Qt::AlignVCenter, + QString::number(mapValue,'f',2)+mapUnit); + for (j = 0; j < minDIVS - 1; j++) { + y += STEPS; + p.drawLine(left, y, left+5, y); + p.drawLine(right, y, right-5, y); + } + y += STEPS; + mapValue -= mapSteps; + } + p.drawLine(left, y, left+10, y); + p.drawText(QRectF(left+15, y-10, 100, 20), + Qt::AlignLeft | Qt::AlignVCenter, + QString::number(mapValue,'f',2)+mapUnit); + p.drawLine(right, y, right-10, y); + p.drawText(QRectF(right-115, y-10, 100, 20), + Qt::AlignRight | Qt::AlignVCenter, + QString::number(mapValue,'f',2)+mapUnit); +} + void AnalogSignal::paint_mid(QPainter &p, int left, int right) { assert(_data); assert(_view); assert(right >= left); - const int y = get_y() + _totalHeight * 0.5; + const int height = get_totalHeight(); + const int top = get_y() - height * 0.5; + const int bottom = get_y() + height * 0.5; + const float zeroY = bottom - _zero_vrate * height ; + const double scale = _view->scale(); assert(scale > 0); const int64_t offset = _view->offset(); const deque< boost::shared_ptr > &snapshots = - _data->get_snapshots(); - if (snapshots.empty()) - return; + _data->get_snapshots(); + if (snapshots.empty()) + return; - _scale = _totalHeight * 1.0f / 65536; - const boost::shared_ptr &snapshot = - snapshots.front(); + const boost::shared_ptr &snapshot = + snapshots.front(); if (snapshot->empty()) return; @@ -101,105 +330,189 @@ void AnalogSignal::paint_mid(QPainter &p, int left, int right) if (order == -1) return; + if (_bits != snapshot->get_unit_bytes()*8) { + _bits = snapshot->get_unit_bytes()*8; + _scale = _totalHeight * 1.0f / ((1 << _bits) - 1); + update_offset(); + } const double pixels_offset = offset; const double samplerate = _data->samplerate(); - const int64_t last_sample = max((int64_t)(snapshot->get_sample_count() - 1), (int64_t)0); - const double samples_per_pixel = samplerate * scale; - const double start = offset * samples_per_pixel; - const double end = start + samples_per_pixel * (right - left); + const int64_t cur_sample_count = snapshot->get_sample_count(); + const double samples_per_pixel = samplerate * scale; + const uint64_t ring_start = snapshot->get_ring_start(); - const int64_t start_sample = min(max((int64_t)floor(start), - (int64_t)0), last_sample); - const int64_t end_sample = min(max((int64_t)ceil(end) + 1, - (int64_t)0), last_sample); +// int64_t start_pixel; +// uint64_t start_index; +// int64_t start_skew_pixels; + //const double first_pos = (_view->session().cur_samplelimits() - cur_sample_count) / samples_per_pixel; + // const double start_sample = (snapshot->get_ring_start() + + // (pixels_offset + left - first_pos) * samples_per_pixel); + //start_pixel = floor(first_pos - pixels_offset - left); + // if (start_sample < 0) { + // start_index = 0; + // start_skew_pixels = 0; + // } else { + // start_index = (uint64_t)(start_sample) % cur_sample_count; + // start_skew_pixels = (start_sample - floor(start_sample)) / samples_per_pixel; + // } + // if (start_pixel < left) + // start_pixel = left; + // start_pixel -= start_skew_pixels; + // int64_t show_length = ceil(samples_per_pixel*(right - start_pixel + 1)); - if (samples_per_pixel < EnvelopeThreshold) - paint_trace(p, snapshot, y, left, - start_sample, end_sample, - pixels_offset, samples_per_pixel, order); - else - paint_envelope(p, snapshot, y, left, - start_sample, end_sample, - pixels_offset, samples_per_pixel, order); + int64_t start_pixel; + uint64_t start_index; + const double over_pixel = cur_sample_count / samples_per_pixel - + pixels_offset - right; + if (over_pixel <= left - right) { + return; + } else if (over_pixel <= 0) { + start_index = ring_start; + start_pixel = over_pixel + right - left; + } else { + const double over_sample = over_pixel * samples_per_pixel; + start_index = (uint64_t)(ring_start + floor(over_sample)) % cur_sample_count; + start_pixel = right + (over_sample - floor(over_sample)) / samples_per_pixel; + } + + int64_t show_length = ceil(samples_per_pixel*(start_pixel + 1)); + if (show_length <= 0) + return; + + if (samples_per_pixel < EnvelopeThreshold) + paint_trace(p, snapshot, zeroY, + start_pixel, start_index, show_length, + samples_per_pixel, order, + top, bottom, right-left); + else + paint_envelope(p, snapshot, zeroY, + start_pixel, start_index, show_length, + samples_per_pixel, order, + top, bottom, right-left); } void AnalogSignal::paint_trace(QPainter &p, - const boost::shared_ptr &snapshot, - int y, int left, const int64_t start, const int64_t end, - const double pixels_offset, const double samples_per_pixel, - int order) + const boost::shared_ptr &snapshot, + int zeroY, const int start_pixel, + const uint64_t start_index, const int64_t sample_count, + const double samples_per_pixel, const int order, + const int top, const int bottom, const int width) { - const int64_t sample_count = end - start; - const int64_t channel_num = snapshot->get_channel_num(); + (void)width; + const int64_t channel_num = snapshot->get_channel_num(); if (sample_count > 0) { - const uint16_t *const samples = snapshot->get_samples(start, end); + const uint8_t unit_bytes = snapshot->get_unit_bytes(); + const uint8_t *const samples = snapshot->get_samples(0); assert(samples); p.setPen(_colour); //p.setPen(QPen(_colour, 2, Qt::SolidLine)); - QPointF *points = new QPointF[sample_count]; - QPointF *point = points; - for (int64_t sample = start; sample != end; sample++) { - const float x = (sample / samples_per_pixel - - pixels_offset) + left; - *point++ = QPointF(x, - y - samples[(sample - start) * channel_num + order] * _scale); + QPointF *points = new QPointF[sample_count + 2]; + QPointF *point = points; + uint64_t yindex = start_index; + int x = 0; +// const int64_t start_offset = start_pixel - (int64_t)(start_index / samples_per_pixel + 0.5); + //for (int64_t sample = 0; x < right; sample++) { + const int64_t start_offset = start_pixel + (int64_t)(start_index / samples_per_pixel + 0.5); + for (int64_t sample = 0; x >= 0; sample++) { + x = start_offset - (start_index + sample) / samples_per_pixel - 0.5; + uint64_t index = (yindex * channel_num + order) * unit_bytes; + double yvalue = samples[index]; + for(uint8_t i = 1; i < unit_bytes; i++) + yvalue += (samples[++index] << i*8); + yvalue = zeroY + ((int)yvalue - _hw_offset) * _scale; + yvalue = min(max((int)yvalue, top), bottom); + *point++ = QPointF(x, yvalue); + if (sample != 0 && yindex == snapshot->get_ring_end()) { + *point++ = QPointF(0, points[sample].y()); + break; + } + yindex++; + yindex %= snapshot->get_sample_count(); } - p.drawPolyline(points, point - points); - //delete[] samples; delete[] points; } } void AnalogSignal::paint_envelope(QPainter &p, - const boost::shared_ptr &snapshot, - int y, int left, const int64_t start, const int64_t end, - const double pixels_offset, const double samples_per_pixel, - int order) + const boost::shared_ptr &snapshot, + int zeroY, const int start_pixel, + const uint64_t start_index, const int64_t sample_count, + const double samples_per_pixel, const int order, + const int top, const int bottom, const int width) { - using namespace Qt; - using pv::data::AnalogSnapshot; + using namespace Qt; + using pv::data::AnalogSnapshot; - AnalogSnapshot::EnvelopeSection e; - snapshot->get_envelope_section(e, start, end, samples_per_pixel, order); - - if (e.length < 2) - return; + AnalogSnapshot::EnvelopeSection e; + snapshot->get_envelope_section(e, start_index, sample_count, + samples_per_pixel, order); + if (e.samples_num == 0) + return; p.setPen(QPen(NoPen)); //p.setPen(QPen(_colour, 2, Qt::SolidLine)); p.setBrush(_colour); - QRectF *const rects = new QRectF[e.length]; - QRectF *rect = rects; + if (!_rects) + _rects = new QRectF[width+3]; + QRectF *rect = _rects; + int px = -1, pre_px; + int y_min, y_max, pre_y_min, pre_y_max; + int pcnt = 0; + const double scale_samples_pre_pixel = samples_per_pixel / e.scale; + const uint64_t ring_end = snapshot->get_ring_end() / e.scale; +// const int64_t start_offset = start_pixel - +// (int64_t)(e.start / scale_samples_pre_pixel + 0.5); +// for(uint64_t sample = 0; sample < e.length; sample++) { + const int64_t start_offset = start_pixel + + (int64_t)(e.start / scale_samples_pre_pixel + 0.5); + for(uint64_t sample = 0; sample < e.length; sample++) { + const uint64_t ring_index = (e.start + sample) % (_view->session().cur_samplelimits() / e.scale); + if (sample != 0 && ring_index == ring_end) + break; +// const int x = start_offset + +// (e.start + sample) / scale_samples_pre_pixel + 0.5; + const int x = start_offset - + (e.start + sample) / scale_samples_pre_pixel - 0.5; + const AnalogSnapshot::EnvelopeSample *const ev = + e.samples + ((e.start + sample) % e.samples_num); - for(uint64_t sample = 0; sample < e.length-1; sample++) { - const float x = ((e.scale * sample + e.start) / - samples_per_pixel - pixels_offset) + left; - const AnalogSnapshot::EnvelopeSample *const s = - e.samples + sample; + const int b = min(max((int)(zeroY + (ev->max - _hw_offset) * _scale + 0.5), top), bottom); + const int t = min(max((int)(zeroY + (ev->min - _hw_offset) * _scale + 0.5), top), bottom); - // We overlap this sample with the next so that vertical - // gaps do not appear during steep rising or falling edges - const float b = y - max(s->max, (s+1)->min) * _scale; - const float t = y - min(s->min, (s+1)->max) * _scale; + pre_px = px; + if(px != x) { + if (pre_px != -1) { + // We overlap this sample with the previous so that vertical + // gaps do not appear during steep rising or falling edges + if (pre_y_min > y_max) + *rect++ = QRectF(pre_px, y_min, 1.0f, pre_y_min-y_min+1); + else if (pre_y_max < y_min) + *rect++ = QRectF(pre_px, pre_y_max, 1.0f, y_max-pre_y_max+1); + else + *rect++ = QRectF(pre_px, y_min, 1.0f, y_max-y_min+1); + pre_y_min = y_min; + pre_y_max = y_max; + pcnt++; + } else { + pre_y_max = min(max(b, top), bottom); + pre_y_min = min(max(t, top), bottom); + } + px = x; + y_max = min(max(b, top), bottom); + y_min = min(max(t, top), bottom); + } + if (px == pre_px) { + y_max = max(b, y_max); + y_min = min(t, y_min); + } + } - float h = b - t; - if(h >= 0.0f && h <= 1.0f) - h = 1.0f; - if(h <= 0.0f && h >= -1.0f) - h = -1.0f; - - *rect++ = QRectF(x, t, 1.0f, h); - } - - p.drawRects(rects, e.length); - - delete[] rects; - //delete[] e.samples; + p.drawRects(_rects, pcnt); } } // namespace view diff --git a/DSView/pv/view/analogsignal.h b/DSView/pv/view/analogsignal.h index 6b8a407e..82689bdc 100644 --- a/DSView/pv/view/analogsignal.h +++ b/DSView/pv/view/analogsignal.h @@ -49,12 +49,51 @@ public: AnalogSignal(boost::shared_ptr dev_inst, boost::shared_ptr data, sr_channel *probe); + AnalogSignal(boost::shared_ptr s, + boost::shared_ptr data, + sr_channel *probe); virtual ~AnalogSignal(); boost::shared_ptr data() const; void set_scale(float scale); + float get_scale() const; + int get_bits() const; + int get_hw_offset() const; + int commit_settings(); + + /** + * Probe options + **/ + uint64_t get_vdiv() const; + uint8_t get_acCoupling() const; + QString get_mapUnit() const; + double get_mapMin() const; + double get_mapMax() const; + + /** + * + **/ + void set_zero_vpos(int pos); + int get_zero_vpos() const; + void set_zero_vrate(double rate, bool force_update); + double get_zero_vrate() const; + void update_vpos(); + void update_offset(); + + /** + * Event + **/ + void resize(); + + /** + * Paints the background layer of the trace with a QPainter + * @param p the QPainter to paint into. + * @param left the x-coordinate of the left edge of the signal + * @param right the x-coordinate of the right edge of the signal + **/ + void paint_back(QPainter &p, int left, int right); /** * Paints the signal with a QPainter @@ -66,18 +105,28 @@ public: private: void paint_trace(QPainter &p, - const boost::shared_ptr &snapshot, - int y, int left, const int64_t start, const int64_t end, - const double pixels_offset, const double samples_per_pixel, int order); + const boost::shared_ptr &snapshot, + int zeroY, const int start_pixel, + const uint64_t start_index, const int64_t sample_count, + const double samples_per_pixel, const int order, + const int top, const int bottom, const int width); void paint_envelope(QPainter &p, - const boost::shared_ptr &snapshot, - int y, int left, const int64_t start, const int64_t end, - const double pixels_offset, const double samples_per_pixel, int order); + const boost::shared_ptr &snapshot, + int zeroY, const int start_pixel, + const uint64_t start_index, const int64_t sample_count, + const double samples_per_pixel, const int order, + const int top, const int bottom, const int width); private: boost::shared_ptr _data; + + QRectF *_rects; + float _scale; + double _zero_vrate; + int _hw_offset; + int _bits; }; } // namespace view diff --git a/DSView/pv/view/devmode.cpp b/DSView/pv/view/devmode.cpp index 93f138e0..f88b6fd6 100644 --- a/DSView/pv/view/devmode.cpp +++ b/DSView/pv/view/devmode.cpp @@ -115,7 +115,10 @@ void DevMode::on_mode_change() i != _mode_button_list.end(); i++) { if ((*i).first == button) { if (dev_inst->dev_inst()->mode != (*i).second->mode) { + _session.set_run_mode(SigSession::Single); + _session.set_repeating(false); _session.stop_capture(); + _session.capture_state_changed(SigSession::Stopped); _session.session_save(); dev_inst->set_config(NULL, NULL, SR_CONF_DEVICE_MODE, diff --git a/DSView/pv/view/dsosignal.cpp b/DSView/pv/view/dsosignal.cpp index 1efc298d..65d56faa 100644 --- a/DSView/pv/view/dsosignal.cpp +++ b/DSView/pv/view/dsosignal.cpp @@ -187,7 +187,7 @@ void DsoSignal::set_enable(bool enable) GVariant* gvar; bool cur_enable; - gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_EN_CH); + gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_PROBE_EN); if (gvar != NULL) { cur_enable = g_variant_get_boolean(gvar); g_variant_unref(gvar); @@ -207,7 +207,7 @@ void DsoSignal::set_enable(bool enable) QCoreApplication::processEvents(); set_vDialActive(false); - _dev_inst->set_config(_probe, NULL, SR_CONF_EN_CH, + _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_EN, g_variant_new_boolean(enable)); if (running) { @@ -237,11 +237,11 @@ bool DsoSignal::go_vDialPre() _view->session().refresh(RefreshShort); const double pre_vdiv = _vDial->get_value(); _vDial->set_sel(_vDial->get_sel() - 1); - _dev_inst->set_config(_probe, NULL, SR_CONF_VDIV, + _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_VDIV, g_variant_new_uint64(_vDial->get_value())); if (_view->session().get_capture_state() == SigSession::Stopped) _scale *= pre_vdiv/_vDial->get_value(); - update_offset(); + update_vpos(); _view->update_calibration(); _view->set_update(_viewport, true); _view->update(); @@ -259,11 +259,11 @@ bool DsoSignal::go_vDialNext() _view->session().refresh(RefreshShort); const double pre_vdiv = _vDial->get_value(); _vDial->set_sel(_vDial->get_sel() + 1); - _dev_inst->set_config(_probe, NULL, SR_CONF_VDIV, + _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_VDIV, g_variant_new_uint64(_vDial->get_value())); if (_view->session().get_capture_state() == SigSession::Stopped) _scale *= pre_vdiv/_vDial->get_value(); - update_offset(); + update_vpos(); _view->update_calibration(); _view->set_update(_viewport, true); _view->update(); @@ -426,23 +426,23 @@ bool DsoSignal::load_settings() // -- enable // bool enable; -// gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_EN_CH); +// gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_PROBE_EN); // if (gvar != NULL) { // enable = g_variant_get_boolean(gvar); // g_variant_unref(gvar); // } else { -// qDebug() << "ERROR: config_get SR_CONF_EN_CH failed."; +// qDebug() << "ERROR: config_get SR_CONF_PROBE_EN failed."; // return false; // } // dso channel bits - gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_DSO_BITS); + gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_UNIT_BITS); if (gvar != NULL) { _bits = g_variant_get_byte(gvar); g_variant_unref(gvar); } else { _bits = DefaultBits; - qDebug("Warning: config_get SR_CONF_DSO_BITS failed, set to %d(default).", DefaultBits); + qDebug("Warning: config_get SR_CONF_UNIT_BITS failed, set to %d(default).", DefaultBits); if (strncmp(_dev_inst->name().toLocal8Bit(), "virtual", 7)) return false; } @@ -469,54 +469,54 @@ bool DsoSignal::load_settings() // -- vdiv uint64_t vdiv; uint64_t vfactor; - gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_VDIV); + gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_PROBE_VDIV); if (gvar != NULL) { vdiv = g_variant_get_uint64(gvar); g_variant_unref(gvar); } else { - qDebug() << "ERROR: config_get SR_CONF_VDIV failed."; + qDebug() << "ERROR: config_get SR_CONF_PROBE_VDIV failed."; return false; } - gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_FACTOR); + gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_PROBE_FACTOR); if (gvar != NULL) { vfactor = g_variant_get_uint64(gvar); g_variant_unref(gvar); } else { - qDebug() << "ERROR: config_get SR_CONF_FACTOR failed."; + qDebug() << "ERROR: config_get SR_CONF_PROBE_FACTOR failed."; return false; } _vDial->set_value(vdiv); _vDial->set_factor(vfactor); -// _dev_inst->set_config(_probe, NULL, SR_CONF_VDIV, +// _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_VDIV, // g_variant_new_uint64(_vDial->get_value())); // -- coupling - gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_COUPLING); + gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_PROBE_COUPLING); if (gvar != NULL) { _acCoupling = g_variant_get_byte(gvar); g_variant_unref(gvar); } else { - qDebug() << "ERROR: config_get SR_CONF_COUPLING failed."; + qDebug() << "ERROR: config_get SR_CONF_PROBE_COUPLING failed."; return false; } -// _dev_inst->set_config(_probe, NULL, SR_CONF_COUPLING, +// _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_COUPLING, // g_variant_new_byte(_acCoupling)); // -- vpos double vpos; - gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_VPOS); + gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_PROBE_VPOS); if (gvar != NULL) { vpos = g_variant_get_double(gvar); g_variant_unref(gvar); } else { - qDebug() << "ERROR: config_get SR_CONF_VPOS failed."; + qDebug() << "ERROR: config_get SR_CONF_PROBE_VPOS failed."; return false; } _zero_vrate = min(max((0.5 - vpos / (_vDial->get_value() * DS_CONF_DSO_VDIVS)), 0.0), 1.0); if (_dev_inst->name().contains("virtual")) - cur_hw_offset = _zero_vrate * ((1 << _bits) - 1); + _hw_offset = _zero_vrate * ((1 << _bits) - 1); // -- trig_value gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_TRIGGER_VALUE); @@ -541,7 +541,7 @@ int DsoSignal::commit_settings() { int ret; // -- enable - ret = _dev_inst->set_config(_probe, NULL, SR_CONF_EN_CH, + ret = _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_EN, g_variant_new_boolean(enabled())); // -- hdiv @@ -549,18 +549,18 @@ int DsoSignal::commit_settings() g_variant_new_uint64(_hDial->get_value())); // -- vdiv - ret = _dev_inst->set_config(_probe, NULL, SR_CONF_VDIV, + ret = _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_VDIV, g_variant_new_uint64(_vDial->get_value())); - ret = _dev_inst->set_config(_probe, NULL, SR_CONF_FACTOR, + ret = _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_FACTOR, g_variant_new_uint64(_vDial->get_factor())); // -- coupling - ret = _dev_inst->set_config(_probe, NULL, SR_CONF_COUPLING, + ret = _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_COUPLING, g_variant_new_byte(_acCoupling)); // -- vpos double vpos_off = (0.5 - (get_zero_vpos() - UpMargin) * 1.0/get_view_rect().height()) * _vDial->get_value() * DS_CONF_DSO_VDIVS; - ret = _dev_inst->set_config(_probe, NULL, SR_CONF_VPOS, + ret = _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_VPOS, g_variant_new_double(vpos_off)); // -- trig_value @@ -599,7 +599,7 @@ void DsoSignal::set_acCoupling(uint8_t coupling) { if (enabled()) { _acCoupling = coupling; - _dev_inst->set_config(_probe, NULL, SR_CONF_COUPLING, + _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_COUPLING, g_variant_new_byte(_acCoupling)); } } @@ -655,7 +655,7 @@ void DsoSignal::set_trig_vrate(double rate) g_variant_new_byte(_trig_value)); } -int DsoSignal::get_zero_vpos() +int DsoSignal::get_zero_vpos() const { return _zero_vrate * get_view_rect().height() + UpMargin; } @@ -667,7 +667,7 @@ double DsoSignal::get_zero_vrate() double DsoSignal::get_hw_offset() { - return cur_hw_offset; + return _hw_offset; } void DsoSignal::set_zero_vpos(int pos) @@ -682,15 +682,15 @@ void DsoSignal::set_zero_vpos(int pos) void DsoSignal::set_zero_vrate(double rate, bool force_update) { _zero_vrate = rate; - update_offset(); + update_vpos(); if (!_dev_inst->name().contains("virtual") && (force_update || _view->session().get_capture_state() == SigSession::Running)) { if (_dev_inst->name() == "DSLogic") - cur_hw_offset = 0x80; + _hw_offset = 0x80; else - cur_hw_offset = _zero_vrate * ((1 << _bits) - 1); + _hw_offset = _zero_vrate * ((1 << _bits) - 1); } } @@ -699,16 +699,16 @@ void DsoSignal::set_factor(uint64_t factor) if (enabled()) { GVariant* gvar; uint64_t prefactor = 0; - gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_FACTOR); + gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_PROBE_FACTOR); if (gvar != NULL) { prefactor = g_variant_get_uint64(gvar); g_variant_unref(gvar); } else { - qDebug() << "ERROR: config_get SR_CONF_FACTOR failed."; + qDebug() << "ERROR: config_get SR_CONF_PROBE_FACTOR failed."; return; } if (prefactor != factor) { - _dev_inst->set_config(_probe, NULL, SR_CONF_FACTOR, + _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_FACTOR, g_variant_new_uint64(factor)); _vDial->set_factor(factor); _view->set_update(_viewport, true); @@ -721,13 +721,13 @@ uint64_t DsoSignal::get_factor() { GVariant* gvar; uint64_t factor; - gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_FACTOR); + gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_PROBE_FACTOR); if (gvar != NULL) { factor = g_variant_get_uint64(gvar); g_variant_unref(gvar); return factor; } else { - qDebug() << "ERROR: config_get SR_CONF_FACTOR failed."; + qDebug() << "ERROR: config_get SR_CONF_PROBE_FACTOR failed."; return 1; } } @@ -786,10 +786,10 @@ QString DsoSignal::get_ms_string(int index) const } } -void DsoSignal::update_offset() +void DsoSignal::update_vpos() { double vpos_off = (0.5 - _zero_vrate) * _vDial->get_value() * DS_CONF_DSO_VDIVS; - _dev_inst->set_config(_probe, NULL, SR_CONF_VPOS, + _dev_inst->set_config(_probe, NULL, SR_CONF_PROBE_VPOS, g_variant_new_double(vpos_off)); } @@ -871,10 +871,11 @@ void DsoSignal::paint_mid(QPainter &p, int left, int right) assert(right >= left); if (enabled()) { + const float top = get_view_rect().top(); const int height = get_view_rect().height(); const int width = right - left; + const float zeroY = _zero_vrate * height + top; - const int y = get_zero_vpos() + height * 0.5; const double scale = _view->scale(); assert(scale > 0); const int64_t offset = _view->offset(); @@ -907,12 +908,12 @@ void DsoSignal::paint_mid(QPainter &p, int left, int right) if (samples_per_pixel < EnvelopeThreshold) { snapshot->enable_envelope(false); - paint_trace(p, snapshot, y, left, + paint_trace(p, snapshot, zeroY, left, start_sample, end_sample, pixels_offset, samples_per_pixel, number_channels); } else { snapshot->enable_envelope(true); - paint_envelope(p, snapshot, y, left, + paint_envelope(p, snapshot, zeroY, left, start_sample, end_sample, pixels_offset, samples_per_pixel, number_channels); } @@ -1014,11 +1015,9 @@ QRectF DsoSignal::get_trig_rect(int left, int right) const void DsoSignal::paint_trace(QPainter &p, const boost::shared_ptr &snapshot, - int y, int left, const int64_t start, const int64_t end, + int zeroY, int left, const int64_t start, const int64_t end, const double pixels_offset, const double samples_per_pixel, uint64_t num_channels) { - (void)y; - const int64_t sample_count = end - start + 1; if (sample_count > 0) { @@ -1034,7 +1033,6 @@ void DsoSignal::paint_trace(QPainter &p, float top = get_view_rect().top(); float bottom = get_view_rect().bottom(); - float zeroP = _zero_vrate * get_view_rect().height() + top;; float x = (start / samples_per_pixel - pixels_offset) + left; double pixels_per_sample = 1.0/samples_per_pixel; uint8_t offset; @@ -1045,7 +1043,7 @@ void DsoSignal::paint_trace(QPainter &p, //offset = samples[(sample - start)*num_channels]; offset = samples[sample]; - const float y = min(max(top, zeroP + (offset - cur_hw_offset) * _scale), bottom); + const float y = min(max(top, zeroY + (offset - _hw_offset) * _scale), bottom); *point++ = QPointF(x, y); x += pixels_per_sample; //*point++ = QPointF(x, top + offset); @@ -1062,14 +1060,12 @@ void DsoSignal::paint_trace(QPainter &p, void DsoSignal::paint_envelope(QPainter &p, const boost::shared_ptr &snapshot, - int y, int left, const int64_t start, const int64_t end, + int zeroY, int left, const int64_t start, const int64_t end, const double pixels_offset, const double samples_per_pixel, uint64_t num_channels) { using namespace Qt; using pv::data::DsoSnapshot; - (void)y; - DsoSnapshot::EnvelopeSection e; const uint16_t index = get_index() % num_channels; snapshot->get_envelope_section(e, start, end, samples_per_pixel, index); @@ -1087,7 +1083,6 @@ void DsoSignal::paint_envelope(QPainter &p, QRectF *rect = rects; float top = get_view_rect().top(); float bottom = get_view_rect().bottom(); - float zeroP = _zero_vrate * get_view_rect().height() + top; for(uint64_t sample = 0; sample < e.length-1; sample++) { const float x = ((e.scale * sample + e.start) / samples_per_pixel - pixels_offset) + left; @@ -1096,8 +1091,8 @@ void DsoSignal::paint_envelope(QPainter &p, // We overlap this sample with the next so that vertical // gaps do not appear during steep rising or falling edges - const float b = min(max(top, ((max(s->max, (s+1)->min) - cur_hw_offset) * _scale + zeroP)), bottom); - const float t = min(max(top, ((min(s->min, (s+1)->max) - cur_hw_offset) * _scale + zeroP)), bottom); + const float b = min(max(top, ((max(s->max, (s+1)->min) - _hw_offset) * _scale + zeroY)), bottom); + const float t = min(max(top, ((min(s->min, (s+1)->max) - _hw_offset) * _scale + zeroY)), bottom); float h = b - t; if(h >= 0.0f && h <= 1.0f) @@ -1147,12 +1142,12 @@ void DsoSignal::paint_type_options(QPainter &p, int right, const QPoint pt) // paint the probe factor selector GVariant* gvar; uint64_t factor; - gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_FACTOR); + gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_PROBE_FACTOR); if (gvar != NULL) { factor = g_variant_get_uint64(gvar); g_variant_unref(gvar); } else { - qDebug() << "ERROR: config_get SR_CONF_FACTOR failed."; + qDebug() << "ERROR: config_get SR_CONF_PROBE_FACTOR failed."; return; } @@ -1351,8 +1346,8 @@ void DsoSignal::paint_measure(QPainter &p) _min = (index == 0) ? status.ch0_min : status.ch1_min; const uint64_t period = (index == 0) ? status.ch0_period : status.ch1_period; const uint32_t count = (index == 0) ? status.ch0_pcnt : status.ch1_pcnt; - double value_max = (cur_hw_offset - _min) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height(); - double value_min = (cur_hw_offset - _max) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height(); + double value_max = (_hw_offset - _min) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height(); + double value_min = (_hw_offset - _max) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height(); double value_p2p = value_max - value_min; _period = (count == 0) ? period * 10.0 : period * 10.0 / count; const int channel_count = _view->session().get_ch_num(SR_CHANNEL_DSO); @@ -1373,7 +1368,7 @@ void DsoSignal::paint_measure(QPainter &p) if (!snapshots.empty()) { const boost::shared_ptr &snapshot = snapshots.front(); - const double vrms = snapshot->cal_vrms(cur_hw_offset, get_index()); + const double vrms = snapshot->cal_vrms(_hw_offset, get_index()); const double value_vrms = vrms * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height(); _ms_string[DSO_MS_VRMS] = tr("Vrms: ") + (abs(value_vrms) > 1000 ? QString::number(value_vrms/1000.0, 'f', 2) + "V" : QString::number(value_vrms, 'f', 2) + "mV"); } @@ -1386,7 +1381,7 @@ void DsoSignal::paint_measure(QPainter &p) const boost::shared_ptr &snapshot = snapshots.front(); const double vmean = snapshot->cal_vmean(get_index()); - const double value_vmean = (cur_hw_offset - vmean) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height(); + const double value_vmean = (_hw_offset - vmean) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height(); _ms_string[DSO_MS_VMEA] = tr("Vmean: ") + (abs(value_vmean) > 1000 ? QString::number(value_vmean/1000.0, 'f', 2) + "V" : QString::number(value_vmean, 'f', 2) + "mV"); } } @@ -1551,17 +1546,17 @@ bool DsoSignal::measure(const QPointF &p) const uint8_t cur_sample = *snapshot->get_samples(_hover_index, _hover_index, get_index()); const uint8_t nxt_sample = *snapshot->get_samples(nxt_index, nxt_index, get_index()); - _hover_value = (cur_hw_offset - cur_sample) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height(); + _hover_value = (_hw_offset - cur_sample) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height(); float top = get_view_rect().top(); float bottom = get_view_rect().bottom(); float zeroP = _zero_vrate * get_view_rect().height() + top; float pre_x = (pre_index / samples_per_pixel - pixels_offset); - const float pre_y = min(max(top, zeroP + (pre_sample - cur_hw_offset)* _scale), bottom); + const float pre_y = min(max(top, zeroP + (pre_sample - _hw_offset)* _scale), bottom); float x = (_hover_index / samples_per_pixel - pixels_offset); - const float y = min(max(top, zeroP + (cur_sample - cur_hw_offset)* _scale), bottom); + const float y = min(max(top, zeroP + (cur_sample - _hw_offset)* _scale), bottom); float nxt_x = (nxt_index / samples_per_pixel - pixels_offset); - const float nxt_y = min(max(top, zeroP + (nxt_sample - cur_hw_offset)* _scale), bottom); + const float nxt_y = min(max(top, zeroP + (nxt_sample - _hw_offset)* _scale), bottom); const QRectF slope_rect = QRectF(QPointF(pre_x - 10, pre_y - 10), QPointF(nxt_x + 10, nxt_y + 10)); if (abs(y-p.y()) < 20 || slope_rect.contains(p)) { _hover_point = QPointF(x, y); diff --git a/DSView/pv/view/dsosignal.h b/DSView/pv/view/dsosignal.h index f8f89cbf..61d3e950 100644 --- a/DSView/pv/view/dsosignal.h +++ b/DSView/pv/view/dsosignal.h @@ -146,7 +146,7 @@ public: /** * Gets the mid-Y position of this signal. */ - int get_zero_vpos(); + int get_zero_vpos() const; double get_zero_vrate(); double get_hw_offset(); /** @@ -154,7 +154,7 @@ public: */ void set_zero_vpos(int pos); void set_zero_vrate(double rate, bool force_update); - void update_offset(); + void update_vpos(); /** * Paints the background layer of the trace with a QPainter @@ -206,13 +206,13 @@ protected: private: void paint_trace(QPainter &p, const boost::shared_ptr &snapshot, - int y, int left, const int64_t start, const int64_t end, + int zeroY, int left, const int64_t start, const int64_t end, const double pixels_offset, const double samples_per_pixel, uint64_t num_channels); void paint_envelope(QPainter &p, const boost::shared_ptr &snapshot, - int y, int left, const int64_t start, const int64_t end, + int zeroY, int left, const int64_t start, const int64_t end, const double pixels_offset, const double samples_per_pixel, uint64_t num_channels); @@ -232,7 +232,7 @@ private: int _trig_value; double _trig_delta; double _zero_vrate; - float cur_hw_offset; + float _hw_offset; uint8_t _max; uint8_t _min; diff --git a/DSView/pv/view/header.cpp b/DSView/pv/view/header.cpp index be28a32b..bd6d4bbd 100644 --- a/DSView/pv/view/header.cpp +++ b/DSView/pv/view/header.cpp @@ -295,7 +295,21 @@ void Header::mouseMoveEvent(QMouseEvent *event) const boost::shared_ptr sig((*i).first); if (sig) { int y = (*i).second + delta; - if (sig->get_type() != SR_CHANNEL_DSO) { + if (sig->get_type() == SR_CHANNEL_DSO) { + boost::shared_ptr dsoSig; + if (dsoSig = dynamic_pointer_cast(sig)) { + dsoSig->set_zero_vpos(y); + _moveFlag = true; + traces_moved(); + } + } else if (sig->get_type() == SR_CHANNEL_ANALOG) { + boost::shared_ptr analogSig; + if (analogSig = dynamic_pointer_cast(sig)) { + analogSig->set_zero_vpos(y); + _moveFlag = true; + traces_moved(); + } + } else { if (~QApplication::keyboardModifiers() & Qt::ControlModifier) { const int y_snap = ((y + View::SignalSnapGridSize / 2) / @@ -306,13 +320,6 @@ void Header::mouseMoveEvent(QMouseEvent *event) sig->set_v_offset(y_snap); } } - } else { - boost::shared_ptr dsoSig; - if (dsoSig = dynamic_pointer_cast(sig)) { - dsoSig->set_zero_vpos(y); - _moveFlag = true; - traces_moved(); - } } } } diff --git a/DSView/pv/view/ruler.cpp b/DSView/pv/view/ruler.cpp index 5c54a321..d42fc1b4 100644 --- a/DSView/pv/view/ruler.cpp +++ b/DSView/pv/view/ruler.cpp @@ -537,7 +537,7 @@ void Ruler::draw_logic_tick_mark(QPainter &p) division++; - } while (x < _view.get_view_width()); + } while (x < rect().right()); // Draw the cursors if (!_view.get_cursorList().empty()) { diff --git a/DSView/pv/view/trace.cpp b/DSView/pv/view/trace.cpp index 1ab65575..e449f474 100644 --- a/DSView/pv/view/trace.cpp +++ b/DSView/pv/view/trace.cpp @@ -188,7 +188,7 @@ void Trace::set_old_v_offset(int v_offset) _old_v_offset = v_offset; } -int Trace::get_zero_vpos() +int Trace::get_zero_vpos() const { return _v_offset; } @@ -203,10 +203,16 @@ void Trace::set_totalHeight(int height) _totalHeight = height; } +void Trace::resize() +{ + +} + void Trace::set_view(pv::view::View *view) { assert(view); _view = view; + connect(_view, SIGNAL(resize()), this, SLOT(resize())); } pv::view::View* Trace::get_view() const @@ -284,7 +290,9 @@ void Trace::paint_label(QPainter &p, int right, const QPoint pt) }; p.setPen(Qt::transparent); - if (_type == SR_CHANNEL_DSO || _type == SR_CHANNEL_FFT) { + if (_type == SR_CHANNEL_DSO || + _type == SR_CHANNEL_FFT || + _type == SR_CHANNEL_ANALOG) { p.setBrush(_colour); p.drawPolygon(points, countof(points)); } else { @@ -324,8 +332,6 @@ void Trace::paint_label(QPainter &p, int right, const QPoint pt) p.setPen(Qt::white); if (_type == SR_CHANNEL_GROUP) p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "G"); - else if (_type == SR_CHANNEL_ANALOG) - p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "A"); else if (_type == SR_CHANNEL_DECODER) p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "D"); else if (_type == SR_CHANNEL_FFT) diff --git a/DSView/pv/view/trace.h b/DSView/pv/view/trace.h index 27ff543a..9440eb01 100644 --- a/DSView/pv/view/trace.h +++ b/DSView/pv/view/trace.h @@ -159,7 +159,7 @@ public: */ void set_old_v_offset(int v_offset); - virtual int get_zero_vpos(); + virtual int get_zero_vpos() const; /** * Returns true if the trace is visible and enabled. @@ -284,8 +284,8 @@ private: private slots: void on_text_changed(const QString &text); - void on_colour_changed(const QColor &colour); + virtual void resize(); signals: void visibility_changed(); diff --git a/DSView/pv/view/view.cpp b/DSView/pv/view/view.cpp index 5dc1e300..9a08688b 100644 --- a/DSView/pv/view/view.cpp +++ b/DSView/pv/view/view.cpp @@ -222,10 +222,14 @@ double View::get_maxscale() const void View::capture_init(bool instant) { + _maxscale = _session.cur_sampletime() / (get_view_width() * MaxViewRate); + if (_session.get_device()->dev_inst()->mode == DSO) show_trig_cursor(true); else if (!_session.isRepeating()) show_trig_cursor(false); + if (_session.get_device()->dev_inst()->mode == ANALOG) + set_scale_offset(_maxscale, 0); update_sample(instant); status_clear(); @@ -284,7 +288,8 @@ void View::zoom(double steps, int offset) _preOffset = _offset; if (_session.get_device()->dev_inst()->mode != DSO) { - _scale *= std::pow(3.0/2.0, -steps); + //_scale *= std::pow(3.0/2.0, -steps); + _scale *= std::pow(2, -steps); _scale = max(min(_scale, _maxscale), _minscale); }else { const vector< boost::shared_ptr > sigs(_session.get_signals()); @@ -808,6 +813,7 @@ void View::resizeEvent(QResizeEvent*) _header->header_resize(); set_update(_time_viewport, true); set_update(_fft_viewport, true); + resize(); } void View::h_scroll_value_changed(int value) @@ -984,7 +990,6 @@ uint64_t View::get_cursor_samples(int index) } curIndex++; } - return ret; } diff --git a/DSView/pv/view/view.h b/DSView/pv/view/view.h index fa95f73d..8cca0a7b 100644 --- a/DSView/pv/view/view.h +++ b/DSView/pv/view/view.h @@ -210,6 +210,8 @@ signals: void update_device_list(); + void resize(); + private: void get_scroll_layout(int64_t &length, int64_t &offset) const; diff --git a/libsigrok4DSL/hardware/DSL/dscope.c b/libsigrok4DSL/hardware/DSL/dscope.c index 49504602..319a25bb 100644 --- a/libsigrok4DSL/hardware/DSL/dscope.c +++ b/libsigrok4DSL/hardware/DSL/dscope.c @@ -26,13 +26,19 @@ static struct sr_dev_mode mode_list[] = { + {"DAQ", ANALOG}, {"OSC", DSO}, }; +enum { + /** Normal */ + OP_NORMAL = 0, + /** Internal pattern test mode */ + OP_INTEST = 1, +}; static const char *opmodes[] = { "Normal", "Internal Test", - "Internal Test", }; static const char *thresholds[] = { @@ -77,7 +83,59 @@ static const char *probe_names[] = { NULL, }; +static const int32_t probeOptions[] = { + SR_CONF_PROBE_COUPLING, + SR_CONF_PROBE_VDIV, + SR_CONF_PROBE_MAP_UNIT, + SR_CONF_PROBE_MAP_MIN, + SR_CONF_PROBE_MAP_MAX, +}; + +static const int32_t probeSessions[] = { + SR_CONF_PROBE_COUPLING, + SR_CONF_PROBE_VDIV, + SR_CONF_PROBE_MAP_UNIT, + SR_CONF_PROBE_MAP_MIN, + SR_CONF_PROBE_MAP_MAX, +}; + +static const uint8_t probeCoupling[] = { + SR_DC_COUPLING, + SR_AC_COUPLING, +}; + +static const uint64_t probeVdivs[] = { + SR_mV(10), + SR_mV(20), + SR_mV(50), + SR_mV(100), + SR_mV(200), + SR_mV(500), + SR_V(1), + SR_V(2), +}; + +static const char *probeMapUnits[] = { + "V", + "A", + "°C", + "°F", + "g", + "m", + "m/s", + "Custom", +}; + static const uint64_t samplerates[] = { + SR_HZ(10), + SR_HZ(20), + SR_HZ(50), + 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), @@ -112,9 +170,10 @@ static const uint64_t samplecounts[] = { SR_MB(8), SR_MB(16), SR_MB(32), + SR_MB(64), + SR_MB(128), }; -static uint16_t opmodes_show_count = 2; static const uint8_t zero_base_addr = 0x40; static const uint8_t zero_big_addr = 0x20; @@ -217,23 +276,40 @@ static uint64_t get_default_vgain(const struct sr_dev_inst *sdi, unsigned int nu return vgain; } +static int counts_size(const struct sr_dev_inst *sdi) +{ + if (strcmp(sdi->model, "DSCope") == 0 || + strcmp(sdi->model, "DSCope20") == 0 || + strcmp(sdi->model, "DSCope B20") == 0) { + if (sdi->mode == DSO) + return 15; + else if (sdi->mode == ANALOG) + return ARRAY_SIZE(samplecounts); + else + return 0; + } else { + return 0; + } +} + static void probe_init(struct sr_dev_inst *sdi) { int i; GSList *l; for (l = sdi->channels; l; l = l->next) { struct sr_channel *probe = (struct sr_channel *)l->data; - if (sdi->mode == DSO) { - probe->vdiv = 1000; - probe->vfactor = 1; - probe->vpos = 0; - probe->coupling = SR_DC_COUPLING; - probe->trig_value = 0x80; - probe->vpos_trans = get_default_trans(sdi); - probe->ms_show = TRUE; - for (i = DSO_MS_BEGIN; i < DSO_MS_END; i++) - probe->ms_en[i] = default_ms_en[i]; - } + probe->vdiv = 1000; + probe->vfactor = 1; + probe->vpos = 0; + probe->coupling = SR_DC_COUPLING; + probe->trig_value = 0x80; + probe->vpos_trans = get_default_trans(sdi); + probe->ms_show = TRUE; + for (i = DSO_MS_BEGIN; i < DSO_MS_END; i++) + probe->ms_en[i] = default_ms_en[i]; + probe->map_unit = probeMapUnits[0]; + probe->map_min = -1; + probe->map_max = 1; } } @@ -243,7 +319,8 @@ static int setup_probes(struct sr_dev_inst *sdi, int num_probes) struct sr_channel *probe; for (j = 0; j < num_probes; j++) { - if (!(probe = sr_channel_new(j, (sdi->mode == LOGIC) ? SR_CHANNEL_LOGIC : ((sdi->mode == DSO) ? SR_CHANNEL_DSO : SR_CHANNEL_ANALOG), + if (!(probe = sr_channel_new(j, (sdi->mode == LOGIC) ? SR_CHANNEL_LOGIC : + ((sdi->mode == DSO) ? SR_CHANNEL_DSO : SR_CHANNEL_ANALOG), TRUE, probe_names[j]))) return SR_ERR; sdi->channels = g_slist_append(sdi->channels, probe); @@ -276,7 +353,7 @@ static int adjust_probes(struct sr_dev_inst *sdi, int num_probes) return SR_OK; } -static struct DSL_context *DSCope_dev_new(void) +static struct DSL_context *DSCope_dev_new(const struct sr_dev_inst *sdi) { struct DSL_context *devc; @@ -294,7 +371,11 @@ static struct DSL_context *DSCope_dev_new(void) devc->clock_type = FALSE; devc->clock_edge = FALSE; devc->instant = FALSE; - devc->op_mode = SR_OP_BUFFER; + devc->op_mode = OP_NORMAL; + devc->test_mode = SR_TEST_NONE; + devc->stream = FALSE; + devc->samplerates_size = ARRAY_SIZE(samplerates); + devc->samplecounts_size = counts_size(sdi); devc->th_level = SR_TH_3V3; devc->filter = SR_FILTER_NONE; devc->timebase = 10000; @@ -306,12 +387,10 @@ static struct DSL_context *DSCope_dev_new(void) devc->zero = FALSE; devc->data_lock = FALSE; devc->cali = FALSE; - devc->dso_bits = 8; + devc->unit_bits = 8; devc->trigger_margin = 8; devc->trigger_channel = 0; devc->rle_mode = FALSE; - devc->stream = FALSE; - return devc; } @@ -402,7 +481,7 @@ static GSList *scan(GSList *options) if (setup_probes(sdi, 2) != SR_OK) return NULL; - devc = DSCope_dev_new(); + devc = DSCope_dev_new(sdi); devc->profile = prof; sdi->priv = devc; drvc->instances = g_slist_append(drvc->instances, sdi); @@ -524,8 +603,8 @@ static uint64_t dso_cmd_gen(const struct sr_dev_inst *sdi, struct sr_channel* ch devc = sdi->priv; switch (id) { - case SR_CONF_EN_CH: - case SR_CONF_COUPLING: + case SR_CONF_PROBE_EN: + case SR_CONF_PROBE_COUPLING: if (devc->zero || dsl_en_ch_num(sdi) == 2) { cmd += 0x0E00; //cmd += 0x000; @@ -544,14 +623,14 @@ static uint64_t dso_cmd_gen(const struct sr_dev_inst *sdi, struct sr_channel* ch else if (ch->coupling == SR_GND_COUPLING) cmd &= 0xFFFFFDFF; break; - case SR_CONF_VDIV: + case SR_CONF_PROBE_VDIV: case SR_CONF_TIMEBASE: cmd += 0x8; cmd += ch->index << ch_bit; // --VGAIN cmd += dso_vga(sdi, ch); break; - case SR_CONF_VPOS: + case SR_CONF_PROBE_VPOS: cmd += 0x10; cmd += ch->index << ch_bit; vpos = dso_vpos(sdi, ch); @@ -606,17 +685,17 @@ static int dso_init(const struct sr_dev_inst *sdi) for(l = sdi->channels; l; l = l->next) { struct sr_channel *probe = (struct sr_channel *)l->data; - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_COUPLING)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_PROBE_COUPLING)); if (ret != SR_OK) { sr_err("DSO set coupling of channel %d command failed!", probe->index); return ret; } - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_VDIV)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_PROBE_VDIV)); if (ret != SR_OK) { sr_err("Set VDIV of channel %d command failed!", probe->index); return ret; } - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_PROBE_VPOS)); if (ret != SR_OK) { sr_err("Set VPOS of channel %d command failed!", probe->index); return ret; @@ -765,6 +844,12 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, return SR_ERR; *data = g_variant_new_boolean(FALSE); break; + case SR_CONF_STREAM: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_boolean(devc->stream); + break; case SR_CONF_MAX_DSO_SAMPLERATE: if (!sdi) return SR_ERR; @@ -780,12 +865,12 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, return SR_ERR; *data = g_variant_new_uint64(DSCOPE_INSTANT_DEPTH); break; - case SR_CONF_VGAIN: + case SR_CONF_PROBE_VGAIN: if (!sdi || !ch) return SR_ERR; *data = g_variant_new_uint64(dso_vga(sdi, ch)>>8); break; - case SR_CONF_VGAIN_DEFAULT: + case SR_CONF_PROBE_VGAIN_DEFAULT: if (!sdi || !ch) return SR_ERR; vga_ptr = get_vga_ptr(sdi); @@ -795,7 +880,7 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, } *data = g_variant_new_uint64(get_default_vgain(sdi, i)>>8); break; - case SR_CONF_VGAIN_RANGE: + case SR_CONF_PROBE_VGAIN_RANGE: if (!sdi) return SR_ERR; vga_ptr = get_vga_ptr(sdi); @@ -806,7 +891,7 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, uint16_t vgain_default= (get_default_vgain(sdi, i)>>8) & 0x0FFF; *data = g_variant_new_uint16(min(CALI_VGAIN_RANGE, vgain_default*2)); break; - case SR_CONF_VOFF: + case SR_CONF_PROBE_VOFF: if (!sdi || !ch) return SR_ERR; uint16_t voff = dso_voff(sdi, ch); @@ -821,16 +906,37 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, } *data = g_variant_new_uint16(voff); break; - case SR_CONF_VOFF_DEFAULT: + case SR_CONF_PROBE_VOFF_DEFAULT: if (!sdi || !ch) return SR_ERR; *data = g_variant_new_uint16(get_default_voff(sdi, ch->index)); break; - case SR_CONF_VOFF_RANGE: + case SR_CONF_PROBE_VOFF_RANGE: if (!sdi) return SR_ERR; *data = g_variant_new_uint16(CALI_VOFF_RANGE); break; + case SR_CONF_PROBE_MAP_UNIT: + if (!sdi || !ch) + return SR_ERR; + *data = g_variant_new_string(ch->map_unit); + break; + case SR_CONF_PROBE_MAP_MIN: + if (!sdi || !ch) + return SR_ERR; + *data = g_variant_new_double(ch->map_min); + break; + case SR_CONF_PROBE_MAP_MAX: + if (!sdi || !ch) + return SR_ERR; + *data = g_variant_new_double(ch->map_max); + break; + case SR_CONF_VLD_CH_NUM: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_int16(DSCOPE_VLD_CH_NUM); + break; default: return SR_ERR_NA; } @@ -868,30 +974,26 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, while(libusb_try_lock_events(drvc->sr_ctx->libusb_ctx)); devc->data_lock = g_variant_get_boolean(data); libusb_unlock_events(drvc->sr_ctx->libusb_ctx); - } else if (id == SR_CONF_VDIV) { + } else if (id == SR_CONF_PROBE_VDIV) { ch->vdiv = g_variant_get_uint64(data); - if (sdi->mode == DSO) { - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_VDIV)); - } + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_PROBE_VDIV)); if (ret == SR_OK) sr_dbg("%s: setting VDIV of channel %d to %d mv", __func__, ch->index, ch->vdiv); else sr_dbg("%s: setting VDIV of channel %d to %d mv failed", __func__, ch->index, ch->vdiv); - } else if (id == SR_CONF_FACTOR) { + } else if (id == SR_CONF_PROBE_FACTOR) { ch->vfactor = g_variant_get_uint64(data); sr_dbg("%s: setting Factor of channel %d to %d", __func__, ch->index, ch->vfactor); } else if (id == SR_CONF_TIMEBASE) { devc->timebase = g_variant_get_uint64(data); - } else if (id == SR_CONF_COUPLING) { + } else if (id == SR_CONF_PROBE_COUPLING) { ch->coupling = g_variant_get_byte(data); if (ch->coupling == SR_GND_COUPLING) ch->coupling = SR_DC_COUPLING; - if (sdi->mode == DSO) { - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_COUPLING)); - } + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_PROBE_COUPLING)); if (ret == SR_OK) sr_dbg("%s: setting AC COUPLING of channel %d to %d", __func__, ch->index, ch->coupling); @@ -973,7 +1075,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, } } else if (id == SR_CONF_INSTANT) { devc->instant = g_variant_get_boolean(data); - if (dsl_en_ch_num(sdi) != 0) { + if (sdi->mode == DSO && dsl_en_ch_num(sdi) != 0) { if (devc->instant) devc->limit_samples = DSCOPE_INSTANT_DEPTH / dsl_en_ch_num(sdi); else @@ -981,43 +1083,62 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, } } else if (id == SR_CONF_DEVICE_MODE) { sdi->mode = g_variant_get_int16(data); - if (sdi->mode == LOGIC) { - num_probes = devc->profile->dev_caps & DEV_CAPS_16BIT ? 16 : 8; - } else if (sdi->mode == DSO) { - sdi->mode = DSO; + if (sdi->mode == DSO) { num_probes = devc->profile->dev_caps & DEV_CAPS_16BIT ? MAX_DSO_PROBES_NUM : 1; ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, NULL, SR_CONF_DSO_SYNC)); if (ret != SR_OK) sr_dbg("%s: DSO configuration sync failed", __func__); - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, sdi->channels->data, SR_CONF_VDIV)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, sdi->channels->data, SR_CONF_PROBE_VDIV)); if (ret == SR_OK) sr_dbg("%s: Initial setting for DSO mode", __func__); else sr_dbg("%s: Initial setting for DSO mode failed", __func__); + devc->op_mode = OP_NORMAL; + devc->test_mode = SR_TEST_NONE; + devc->stream = FALSE; + devc->instant = FALSE; + devc->samplerates_size = ARRAY_SIZE(samplerates); devc->cur_samplerate = DSCOPE_MAX_SAMPLERATE / num_probes; devc->limit_samples = DSCOPE_MAX_DEPTH / num_probes; + } else if (sdi->mode == ANALOG) { + num_probes = devc->profile->dev_caps & DEV_CAPS_16BIT ? MAX_DSO_PROBES_NUM : 1; + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, sdi->channels->data, SR_CONF_PROBE_VDIV)); + if (ret == SR_OK) + sr_dbg("%s: Initial setting for DSO mode", __func__); + else + sr_dbg("%s: Initial setting for DSO mode failed", __func__); + devc->op_mode = OP_NORMAL; + devc->test_mode = SR_TEST_NONE; + devc->stream = TRUE; + devc->instant = TRUE; + devc->samplerates_size = 19; + devc->cur_samplerate = SR_MHZ(1); + devc->limit_samples = SR_MB(16); } else { - num_probes = devc->profile->dev_caps & DEV_CAPS_16BIT ? MAX_ANALOG_PROBES_NUM : 1; + num_probes = 0; } + devc->samplecounts_size = counts_size(sdi); sr_dev_probes_free(sdi); setup_probes(sdi, num_probes); sr_dbg("%s: setting mode to %d", __func__, sdi->mode); } else if (id == SR_CONF_OPERATION_MODE) { stropt = g_variant_get_string(data, NULL); - 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; + if (!strcmp(stropt, opmodes[OP_NORMAL])) { + devc->op_mode = OP_NORMAL; + devc->test_mode = SR_TEST_NONE; + } else if (!strcmp(stropt, opmodes[OP_INTEST])) { + devc->op_mode = OP_INTEST; + devc->test_mode = SR_TEST_INTERNAL; } else { ret = SR_ERR; } sr_dbg("%s: setting pattern to %d", __func__, devc->op_mode); - } else if (id == SR_CONF_EN_CH) { + } else if (id == SR_CONF_PROBE_EN) { ch->enabled = g_variant_get_boolean(data); if (sdi->mode == DSO) { - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_EN_CH)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_PROBE_EN)); if (dsl_en_ch_num(sdi) != 0) { ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, 0, SR_CONF_SAMPLERATE)); } @@ -1028,11 +1149,9 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, else sr_dbg("%s: setting ENABLE of channel %d to %d failed", __func__, ch->index, ch->enabled); - } else if (id == SR_CONF_VPOS) { + } else if (id == SR_CONF_PROBE_VPOS) { ch->vpos = g_variant_get_double(data); - if (sdi->mode == DSO) { - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_VPOS)); - } + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_PROBE_VPOS)); if (ret == SR_OK) sr_dbg("%s: setting VPOS of channel %d to %lf mv", __func__, ch->index, ch->vpos); @@ -1151,7 +1270,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, } else if (id == SR_CONF_VOCM) { const uint8_t vocm = g_variant_get_byte(data); ret = dsl_wr_reg(sdi, COMB_ADDR+4, vocm); - } else if (id == SR_CONF_VGAIN) { + } else if (id == SR_CONF_PROBE_VGAIN) { const uint64_t vgain = g_variant_get_uint64(data) << 8; int i; struct DSL_vga *vga_ptr = get_vga_ptr(sdi); @@ -1163,14 +1282,14 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, (vga_ptr+i)->vgain1 = vgain; } } - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_VDIV)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_PROBE_VDIV)); if (ret == SR_OK) sr_dbg("%s: setting VDIV of channel %d to %d mv", __func__, ch->index, ch->vdiv); else sr_dbg("%s: setting VDIV of channel %d to %d mv failed", __func__, ch->index, ch->vdiv); - } else if (id == SR_CONF_VOFF) { + } else if (id == SR_CONF_PROBE_VOFF) { uint16_t voff = g_variant_get_uint16(data); if (strcmp(sdi->model, "DSCope") == 0) { double voltage_off = (2.0 * voff / CALI_VOFF_RANGE - 1) * ch->vdiv; @@ -1194,13 +1313,19 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, (vga_ptr+i)->voff1 = voff; } } - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_PROBE_VPOS)); if (ret == SR_OK) 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 %lf mv failed", __func__, ch->index, ch->vpos); + } else if (id == SR_CONF_PROBE_MAP_UNIT) { + ch->map_unit = g_variant_get_string(data, NULL); + } else if (id == SR_CONF_PROBE_MAP_MIN) { + ch->map_min = g_variant_get_double(data); + } else if (id == SR_CONF_PROBE_MAP_MAX) { + ch->map_max = g_variant_get_double(data); } else { ret = SR_ERR_NA; } @@ -1211,11 +1336,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)sdi; (void)cg; + devc = sdi->priv; switch (key) { case SR_CONF_SCAN_OPTIONS: @@ -1245,14 +1372,14 @@ 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; case SR_CONF_LIMIT_SAMPLES: g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}")); gvar = g_variant_new_from_data(G_VARIANT_TYPE("at"), - samplecounts, ARRAY_SIZE(samplecounts)*sizeof(uint64_t), TRUE, NULL, NULL); + samplecounts, devc->samplecounts_size*sizeof(uint64_t), TRUE, NULL, NULL); g_variant_builder_add(&gvb, "{sv}", "samplecounts", gvar); *data = g_variant_builder_end(&gvb); break; @@ -1260,11 +1387,37 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, *data = g_variant_new_string(TRIGGER_TYPE); break; case SR_CONF_OPERATION_MODE: - *data = g_variant_new_strv(opmodes, opmodes_show_count); + *data = g_variant_new_strv(opmodes, ARRAY_SIZE(opmodes)); break; case SR_CONF_THRESHOLD: *data = g_variant_new_strv(thresholds, ARRAY_SIZE(thresholds)); break; + + case SR_CONF_PROBE_CONFIGS: + *data = g_variant_new_from_data(G_VARIANT_TYPE("ai"), + probeOptions, ARRAY_SIZE(probeOptions)*sizeof(int32_t), TRUE, NULL, NULL); + break; + case SR_CONF_PROBE_SESSIONS: + *data = g_variant_new_from_data(G_VARIANT_TYPE("ai"), + probeSessions, ARRAY_SIZE(probeSessions)*sizeof(int32_t), TRUE, NULL, NULL); + break; + case SR_CONF_PROBE_VDIV: + g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}")); + gvar = g_variant_new_from_data(G_VARIANT_TYPE("at"), + probeVdivs, ARRAY_SIZE(probeVdivs)*sizeof(uint64_t), TRUE, NULL, NULL); + g_variant_builder_add(&gvb, "{sv}", "vdivs", gvar); + *data = g_variant_builder_end(&gvb); + break; + case SR_CONF_PROBE_COUPLING: + g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}")); + gvar = g_variant_new_from_data(G_VARIANT_TYPE("ay"), + probeCoupling, ARRAY_SIZE(probeCoupling)*sizeof(uint8_t), TRUE, NULL, NULL); + g_variant_builder_add(&gvb, "{sv}", "coupling", gvar); + *data = g_variant_builder_end(&gvb); + break; + case SR_CONF_PROBE_MAP_UNIT: + *data = g_variant_new_strv(probeMapUnits, ARRAY_SIZE(probeMapUnits)); + break; default: return SR_ERR_NA; } @@ -1302,14 +1455,14 @@ static int dso_zero(const struct sr_dev_inst *sdi) probe0->vpos = (vga_ptr+devc->zero_stage-1)->key * -4.8; vdiv_back[0] = probe0->vdiv; probe0->vdiv = (vga_ptr+devc->zero_stage-1)->key; - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_PROBE_VPOS)); } else if (devc->zero_pcnt == 4) { const double voff = 255*0.98 - (devc->mstatus.ch0_max + devc->mstatus.ch0_min) / 2.0; if (abs(voff) < 0.5) { probe0->vpos = vpos_back[0]; } else { probe0->vpos_trans += voff; - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_PROBE_VPOS)); devc->zero_pcnt = 1; } } else if (devc->zero_pcnt == 5) { @@ -1318,14 +1471,14 @@ static int dso_zero(const struct sr_dev_inst *sdi) probe1->vpos = (vga_ptr+devc->zero_stage-1)->key * -4.8; vdiv_back[1] = probe1->vdiv; probe1->vdiv = (vga_ptr+devc->zero_stage-1)->key; - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe1, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe1, SR_CONF_PROBE_VPOS)); } else if (devc->zero_pcnt == 9) { const double voff = 255*0.98 - (devc->mstatus.ch1_max + devc->mstatus.ch1_min) / 2.0; if (abs(voff) < 0.5) { probe1->vpos = vpos_back[1]; } else { probe1->vpos_trans += voff; - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe1, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe1, SR_CONF_PROBE_VPOS)); devc->zero_pcnt = 6; } } @@ -1336,17 +1489,17 @@ static int dso_zero(const struct sr_dev_inst *sdi) devc->zero_comb = 0; vpos_back[0] = probe0->vpos; probe0->vpos = (vga_ptr+devc->zero_stage-1)->key * 4.5; - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_PROBE_VPOS)); } else if (devc->zero_pcnt == 15) { probe0->comb_diff_top = (devc->mstatus.ch0_max - devc->mstatus.ch1_max) + (devc->mstatus.ch0_min - devc->mstatus.ch1_min); probe0->vpos = (vga_ptr+devc->zero_stage-1)->key * -4.5; - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_PROBE_VPOS)); } else if (devc->zero_pcnt == 20) { probe0->comb_diff_bom = (devc->mstatus.ch0_max - devc->mstatus.ch1_max) + (devc->mstatus.ch0_min - devc->mstatus.ch1_min); probe0->vpos = vpos_back[0]; - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe0, SR_CONF_PROBE_VPOS)); } if (devc->zero_pcnt == 25) { @@ -1354,17 +1507,17 @@ static int dso_zero(const struct sr_dev_inst *sdi) devc->zero_comb = 1; vpos_back[1] = probe1->vpos; probe1->vpos = (vga_ptr+devc->zero_stage-1)->key * 4.5; - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe1, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe1, SR_CONF_PROBE_VPOS)); } else if (devc->zero_pcnt == 30) { probe1->comb_diff_top = (devc->mstatus.ch1_max - devc->mstatus.ch0_max) + (devc->mstatus.ch1_min - devc->mstatus.ch0_min); probe1->vpos = (vga_ptr+devc->zero_stage-1)->key * -4.5; - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe1, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe1, SR_CONF_PROBE_VPOS)); } else if (devc->zero_pcnt == 35) { probe1->comb_diff_bom = (devc->mstatus.ch1_max - devc->mstatus.ch0_max) + (devc->mstatus.ch1_min - devc->mstatus.ch0_min); probe1->vpos = vpos_back[1]; - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe1, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe1, SR_CONF_PROBE_VPOS)); } if (devc->zero_pcnt == 40) { @@ -1385,8 +1538,8 @@ static int dso_zero(const struct sr_dev_inst *sdi) struct sr_channel *probe = (struct sr_channel *)l->data; uint64_t vdiv_back = probe->vdiv; probe->vdiv = (vga_ptr+devc->zero_stage)->key; - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_VDIV)); - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_VPOS)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_PROBE_VDIV)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_PROBE_VPOS)); probe->vdiv = vdiv_back; } } diff --git a/libsigrok4DSL/hardware/DSL/dsl.c b/libsigrok4DSL/hardware/DSL/dsl.c index 03fe43b2..85638499 100755 --- a/libsigrok4DSL/hardware/DSL/dsl.c +++ b/libsigrok4DSL/hardware/DSL/dsl.c @@ -390,25 +390,42 @@ SR_PRIV int dsl_fpga_arm(const struct sr_dev_inst *sdi) setting.end_sync = 0xfa5afa5a; // basic configuration +// setting.mode = (trigger->trigger_en << TRIG_EN_BIT) + +// (devc->clock_type << CLK_TYPE_BIT) + +// (devc->clock_edge << CLK_EDGE_BIT) + +// (devc->rle_mode << RLE_MODE_BIT) + +// ((sdi->mode == DSO) << DSO_MODE_BIT) + +// ((((devc->cur_samplerate == (2 * DSLOGIC_MAX_LOGIC_SAMPLERATE)) && sdi->mode != DSO) || (sdi->mode == ANALOG)) << HALF_MODE_BIT) + +// ((devc->cur_samplerate == (4 * DSLOGIC_MAX_LOGIC_SAMPLERATE)) << QUAR_MODE_BIT) + +// ((sdi->mode == ANALOG) << ANALOG_MODE_BIT) + +// ((devc->filter == SR_FILTER_1T) << FILTER_BIT) + +// (devc->instant << INSTANT_BIT) + +// ((trigger->trigger_mode == SERIAL_TRIGGER) << STRIG_MODE_BIT) + +// ((devc->stream) << STREAM_MODE_BIT) + +// ((devc->op_mode == SR_OP_LA_LPTEST) << LPB_TEST_BIT) + +// ((devc->op_mode == SR_OP_LA_EXTEST) << EXT_TEST_BIT) + +// ((devc->op_mode == SR_OP_LA_INTEST) << INT_TEST_BIT); setting.mode = (trigger->trigger_en << TRIG_EN_BIT) + (devc->clock_type << CLK_TYPE_BIT) + (devc->clock_edge << CLK_EDGE_BIT) + (devc->rle_mode << RLE_MODE_BIT) + ((sdi->mode == DSO) << DSO_MODE_BIT) + - ((((devc->cur_samplerate == (2 * DSLOGIC_MAX_LOGIC_SAMPLERATE)) && sdi->mode != DSO) || (sdi->mode == ANALOG)) << HALF_MODE_BIT) + + (((devc->cur_samplerate == (2 * DSLOGIC_MAX_LOGIC_SAMPLERATE)) && sdi->mode != DSO) << HALF_MODE_BIT) + ((devc->cur_samplerate == (4 * DSLOGIC_MAX_LOGIC_SAMPLERATE)) << QUAR_MODE_BIT) + ((sdi->mode == ANALOG) << ANALOG_MODE_BIT) + ((devc->filter == SR_FILTER_1T) << FILTER_BIT) + (devc->instant << INSTANT_BIT) + ((trigger->trigger_mode == SERIAL_TRIGGER) << STRIG_MODE_BIT) + ((devc->stream) << STREAM_MODE_BIT) + - ((devc->op_mode == SR_OP_LOOPBACK_TEST) << LPB_TEST_BIT) + - ((devc->op_mode == SR_OP_EXTERNAL_TEST) << EXT_TEST_BIT) + - ((devc->op_mode == SR_OP_INTERNAL_TEST) << INT_TEST_BIT); + ((devc->test_mode == SR_TEST_LOOPBACK) << LPB_TEST_BIT) + + ((devc->test_mode == SR_TEST_EXTERNAL) << EXT_TEST_BIT) + + ((devc->test_mode == SR_TEST_INTERNAL) << INT_TEST_BIT); // sample rate divider tmp_u32 = (sdi->mode == DSO) ? (uint32_t)ceil(DSLOGIC_MAX_DSO_SAMPLERATE * 1.0 / devc->cur_samplerate / ch_num) : - (uint32_t)ceil(DSLOGIC_MAX_LOGIC_SAMPLERATE * 1.0 / devc->cur_samplerate); + (sdi->mode == ANALOG) ? (uint32_t)ceil(DSCOPE_MAX_DAQ_SAMPLERATE * 1.0 / max(devc->cur_samplerate, HW_MIN_SAMPLERATE)) : + (uint32_t)ceil(DSLOGIC_MAX_LOGIC_SAMPLERATE * 1.0 / devc->cur_samplerate); + devc->unit_pitch = ceil(HW_MIN_SAMPLERATE * 1.0 / devc->cur_samplerate); setting.div_l = tmp_u32 & 0x0000ffff; setting.div_h = tmp_u32 >> 16; @@ -840,17 +857,17 @@ SR_PRIV int dsl_config_get(int id, GVariant **data, const struct sr_dev_inst *sd devc = sdi->priv; *data = g_variant_new_boolean(devc->instant); break; - case SR_CONF_VDIV: + case SR_CONF_PROBE_VDIV: if (!ch) return SR_ERR; *data = g_variant_new_uint64(ch->vdiv); break; - case SR_CONF_FACTOR: + case SR_CONF_PROBE_FACTOR: if (!ch) return SR_ERR; *data = g_variant_new_uint64(ch->vfactor); break; - case SR_CONF_VPOS: + case SR_CONF_PROBE_VPOS: if (!ch) return SR_ERR; *data = g_variant_new_double(ch->vpos); @@ -861,12 +878,12 @@ SR_PRIV int dsl_config_get(int id, GVariant **data, const struct sr_dev_inst *sd devc = sdi->priv; *data = g_variant_new_uint64(devc->timebase); break; - case SR_CONF_COUPLING: + case SR_CONF_PROBE_COUPLING: if (!ch) return SR_ERR; *data = g_variant_new_byte(ch->coupling); break; - case SR_CONF_EN_CH: + case SR_CONF_PROBE_EN: if (!ch) return SR_ERR; *data = g_variant_new_boolean(ch->enabled); @@ -937,11 +954,11 @@ SR_PRIV int dsl_config_get(int id, GVariant **data, const struct sr_dev_inst *sd devc = sdi->priv; *data = g_variant_new_boolean(devc->roll); break; - case SR_CONF_DSO_BITS: + case SR_CONF_UNIT_BITS: if (!sdi) return SR_ERR; devc = sdi->priv; - *data = g_variant_new_byte(devc->dso_bits); + *data = g_variant_new_byte(devc->unit_bits); break; default: return SR_ERR_NA; @@ -1111,10 +1128,17 @@ SR_PRIV int dsl_dev_status_get(const struct sr_dev_inst *sdi, struct sr_status * static unsigned int to_bytes_per_ms(struct DSL_context *devc) { struct sr_dev_inst *sdi = devc->cb_data; - if (devc->cur_samplerate > SR_MHZ(100)) - return SR_MHZ(100) / 1000 * dsl_en_ch_num(sdi) / 8; - else - return devc->cur_samplerate / 1000 * dsl_en_ch_num(sdi) / 8; + if (sdi->mode == LOGIC) { + if (devc->cur_samplerate > SR_MHZ(100)) + return SR_MHZ(100) / 1000 * dsl_en_ch_num(sdi) / 8; + else + return ceil(devc->cur_samplerate / 1000.0 * dsl_en_ch_num(sdi) / 8); + } else { + if (devc->cur_samplerate > SR_MHZ(100)) + return SR_MHZ(100) / 1000.0 * dsl_en_ch_num(sdi); + else + return ceil(devc->cur_samplerate / 1000.0 * dsl_en_ch_num(sdi)); + } } static size_t get_buffer_size(struct DSL_context *devc) @@ -1150,7 +1174,7 @@ SR_PRIV unsigned int dsl_get_timeout(struct DSL_context *devc) total_size = get_buffer_size(devc) * get_number_of_transfers(devc); timeout = total_size / to_bytes_per_ms(devc); - if (devc->op_mode == SR_OP_STREAM) + if (devc->stream) return timeout + timeout / 4; /* Leave a headroom of 25% percent. */ else return 1000; @@ -1307,12 +1331,14 @@ static void receive_transfer(struct libusb_transfer *transfer) packet.status = SR_PKT_DATA_ERROR; devc->mstatus_valid = FALSE; } - } else { + } else if (sdi->mode == ANALOG) { packet.type = SR_DF_ANALOG; packet.payload = &analog; analog.probes = sdi->channels; - cur_sample_count = transfer->actual_length / (sample_width * g_slist_length(analog.probes)); + cur_sample_count = transfer->actual_length / (((devc->unit_bits + 7) / 8) * g_slist_length(analog.probes)); analog.num_samples = cur_sample_count; + analog.unit_bits = devc->unit_bits; + analog.unit_pitch = devc->unit_pitch; analog.mq = SR_MQ_VOLTAGE; analog.unit = SR_UNIT_VOLT; analog.mqflags = SR_MQFLAG_AC; @@ -1341,7 +1367,7 @@ static void receive_transfer(struct libusb_transfer *transfer) devc->limit_samples && devc->num_bytes >= devc->actual_bytes) { devc->status = DSL_STOP; - } else if ((sdi->mode != DSO || devc->instant) && + } else if ((sdi->mode == DSO && devc->instant) && devc->limit_samples && devc->num_samples >= devc->actual_samples) { devc->status = DSL_STOP; diff --git a/libsigrok4DSL/hardware/DSL/dsl.h b/libsigrok4DSL/hardware/DSL/dsl.h index c0ba64eb..dc166736 100644 --- a/libsigrok4DSL/hardware/DSL/dsl.h +++ b/libsigrok4DSL/hardware/DSL/dsl.h @@ -95,6 +95,9 @@ //#define DSCOPE_MAX_DEPTH SR_KB(512) #define DSCOPE_MAX_SAMPLERATE SR_MHZ(200) #define DSCOPE_INSTANT_DEPTH SR_MB(32) +#define DSCOPE_VLD_CH_NUM 2 +#define DSCOPE_MAX_DAQ_SAMPLERATE SR_MHZ(100) +#define HW_MIN_SAMPLERATE SR_KHZ(10) /* * for basic configuration @@ -303,6 +306,8 @@ struct DSL_context { gboolean rle_mode; gboolean instant; uint16_t op_mode; + gboolean stream; + uint8_t test_mode; uint16_t buf_options; uint16_t ch_mode; uint16_t samplerates_size; @@ -328,10 +333,10 @@ struct DSL_context { int zero_stage; int zero_pcnt; int zero_comb; - gboolean stream; gboolean roll; gboolean data_lock; - uint8_t dso_bits; + uint8_t unit_bits; + uint16_t unit_pitch; uint64_t num_samples; uint64_t num_bytes; diff --git a/libsigrok4DSL/hardware/DSL/dslogic.c b/libsigrok4DSL/hardware/DSL/dslogic.c index 77b421f4..efe22aa6 100755 --- a/libsigrok4DSL/hardware/DSL/dslogic.c +++ b/libsigrok4DSL/hardware/DSL/dslogic.c @@ -35,6 +35,18 @@ static struct sr_dev_mode pro_mode_list[] = { {"LA", LOGIC}, }; +enum { + /** Buffer mode */ + OP_BUFFER = 0, + /** Stream mode */ + OP_STREAM = 1, + /** Internal pattern test mode */ + OP_INTEST = 2, + /** External pattern test mode */ + OP_EXTEST = 3, + /** SDRAM loopback test mode */ + OP_LPTEST = 4, +}; static const char *opmodes[] = { "Buffer Mode", "Stream Mode", @@ -244,7 +256,7 @@ static int counts_size(const struct sr_dev_inst *sdi) if (strcmp(sdi->model, "DSLogic Basic") == 0) if (sdi->mode == ANALOG) return 5; - else if (!devc || devc->op_mode == SR_OP_STREAM) + else if (!devc || devc->stream) return ARRAY_SIZE(samplecounts); else return 15; @@ -332,7 +344,9 @@ static struct DSL_context *DSLogic_dev_new(const struct sr_dev_inst *sdi) devc->clock_edge = FALSE; devc->rle_mode = FALSE; devc->instant = FALSE; - devc->op_mode = SR_OP_STREAM; + devc->op_mode = OP_STREAM; + devc->test_mode = SR_TEST_NONE; + devc->stream = (devc->op_mode == OP_STREAM); devc->buf_options = SR_BUF_UPLOAD; devc->ch_mode = 0; devc->samplerates_size = 11; @@ -347,11 +361,11 @@ static struct DSL_context *DSLogic_dev_new(const struct sr_dev_inst *sdi) devc->trigger_hrate = 0; devc->trigger_holdoff = 0; devc->zero = FALSE; - devc->stream = (devc->op_mode == SR_OP_STREAM); + devc->mstatus_valid = FALSE; devc->data_lock = FALSE; devc->max_height = 0; - devc->dso_bits = 8; + devc->unit_bits = 8; devc->trigger_margin = 8; devc->trigger_channel = 0; @@ -521,10 +535,10 @@ static uint64_t dso_cmd_gen(const struct sr_dev_inst *sdi, struct sr_channel* ch devc = sdi->priv; switch (id) { - case SR_CONF_VDIV: - case SR_CONF_EN_CH: + case SR_CONF_PROBE_VDIV: + case SR_CONF_PROBE_EN: case SR_CONF_TIMEBASE: - case SR_CONF_COUPLING: + case SR_CONF_PROBE_COUPLING: for (l = sdi->channels; l; l = l->next) { struct sr_channel *probe = (struct sr_channel *)l->data; if (probe->enabled) { @@ -636,12 +650,12 @@ static int dso_init(const struct sr_dev_inst *sdi) for(l = sdi->channels; l; l = l->next) { struct sr_channel *probe = (struct sr_channel *)l->data; - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_COUPLING)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_PROBE_COUPLING)); if (ret != SR_OK) { sr_err("DSO set coupling of channel %d command failed!", probe->index); return ret; } - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_VDIV)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, probe, SR_CONF_PROBE_VDIV)); if (ret != SR_OK) { sr_err("Set VDIV of channel %d command failed!", probe->index); return ret; @@ -718,8 +732,7 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, if (!sdi) return SR_ERR; devc = sdi->priv; - *data = g_variant_new_boolean((devc->op_mode != SR_OP_BUFFER) && - (devc->op_mode != SR_OP_STREAM)); + *data = g_variant_new_boolean(devc->test_mode != SR_TEST_NONE); break; case SR_CONF_ACTUAL_SAMPLES: if (!sdi) @@ -859,10 +872,10 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, while(libusb_try_lock_events(drvc->sr_ctx->libusb_ctx)); devc->data_lock = g_variant_get_boolean(data); libusb_unlock_events(drvc->sr_ctx->libusb_ctx); - } else if (id == SR_CONF_VDIV) { + } else if (id == SR_CONF_PROBE_VDIV) { ch->vdiv = g_variant_get_uint64(data); if (sdi->mode == DSO) { - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_VDIV)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_PROBE_VDIV)); } if (ret == SR_OK) sr_dbg("%s: setting VDIV of channel %d to %d mv", @@ -870,18 +883,18 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, else sr_dbg("%s: setting VDIV of channel %d to %d mv failed", __func__, ch->index, ch->vdiv); - } else if (id == SR_CONF_FACTOR) { + } else if (id == SR_CONF_PROBE_FACTOR) { ch->vfactor = g_variant_get_uint64(data); sr_dbg("%s: setting Factor of channel %d to %d", __func__, ch->index, ch->vfactor); } else if (id == SR_CONF_TIMEBASE) { devc->timebase = g_variant_get_uint64(data); - } else if (id == SR_CONF_COUPLING) { + } else if (id == SR_CONF_PROBE_COUPLING) { ch->coupling = g_variant_get_byte(data); if (ch->coupling == SR_GND_COUPLING) ch->coupling = SR_DC_COUPLING; if (sdi->mode == DSO) { - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_COUPLING)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_PROBE_COUPLING)); } if (ret == SR_OK) sr_dbg("%s: setting AC COUPLING of channel %d to %d", @@ -952,8 +965,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, sr_dbg("%s: setting Trigger Margin to %d failed", __func__, devc->trigger_margin); } else if (id == SR_CONF_SAMPLERATE) { - if ((devc->op_mode != SR_OP_INTERNAL_TEST) && - (devc->op_mode != SR_OP_EXTERNAL_TEST)) { + if (devc->test_mode != SR_TEST_NONE) { devc->cur_samplerate = g_variant_get_uint64(data); if(sdi->mode == DSO) { devc->sample_wide = (devc->cur_samplerate <= DSLOGIC_MAX_DSO_SAMPLERATE); @@ -1002,7 +1014,8 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, } else { dsl_wr_reg(sdi, EEWP_ADDR, bmSCOPE_CLR); num_probes = devc->profile->dev_caps & DEV_CAPS_16BIT ? MAX_ANALOG_PROBES_NUM : 1; - devc->op_mode = SR_OP_STREAM; + devc->op_mode = OP_STREAM; + devc->test_mode = SR_TEST_NONE; devc->stream = TRUE; devc->samplerates_size = 10; } @@ -1016,20 +1029,23 @@ 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); if (sdi->mode == LOGIC) { - if (!strcmp(stropt, opmodes[SR_OP_BUFFER]) && (devc->op_mode != SR_OP_BUFFER)) { - devc->op_mode = SR_OP_BUFFER; + if (!strcmp(stropt, opmodes[OP_BUFFER]) && (devc->op_mode != OP_BUFFER)) { + devc->op_mode = OP_BUFFER; + devc->test_mode = SR_TEST_NONE; devc->stream = FALSE; devc->ch_mode = 0; devc->samplerates_size = 14; adjust_probes(sdi, MAX_LOGIC_PROBES); - } else if (!strcmp(stropt, opmodes[SR_OP_STREAM]) && (devc->op_mode != SR_OP_STREAM)) { - devc->op_mode = SR_OP_STREAM; + } else if (!strcmp(stropt, opmodes[OP_STREAM]) && (devc->op_mode != OP_STREAM)) { + devc->op_mode = OP_STREAM; + devc->test_mode = SR_TEST_NONE; devc->stream = TRUE; devc->ch_mode = 0; devc->samplerates_size = 11; adjust_probes(sdi, MAX_LOGIC_PROBES); - } else if (!strcmp(stropt, opmodes[SR_OP_INTERNAL_TEST]) && (devc->op_mode != SR_OP_INTERNAL_TEST)) { - devc->op_mode = SR_OP_INTERNAL_TEST; + } else if (!strcmp(stropt, opmodes[OP_INTEST]) && (devc->op_mode != OP_INTEST)) { + devc->op_mode = OP_INTEST; + devc->test_mode = SR_TEST_INTERNAL; if (strcmp(sdi->model, "DSLogic Basic") == 0) { devc->stream = TRUE; devc->samplerates_size = 10; @@ -1042,8 +1058,9 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, devc->limit_samples = DSLOGIC_MAX_LOGIC_DEPTH; devc->cur_samplerate = DSLOGIC_MAX_LOGIC_SAMPLERATE; devc->sample_wide = TRUE; - } else if (!strcmp(stropt, opmodes[SR_OP_EXTERNAL_TEST]) && (devc->op_mode != SR_OP_EXTERNAL_TEST)) { - devc->op_mode = SR_OP_EXTERNAL_TEST; + } else if (!strcmp(stropt, opmodes[OP_EXTEST]) && (devc->op_mode != OP_EXTEST)) { + devc->op_mode = OP_EXTEST; + devc->test_mode = SR_TEST_EXTERNAL; if (strcmp(sdi->model, "DSLogic Basic") == 0) { devc->stream = TRUE; devc->samplerates_size = 11; @@ -1056,8 +1073,9 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, devc->limit_samples = DSLOGIC_MAX_LOGIC_DEPTH; devc->cur_samplerate = DSLOGIC_MAX_LOGIC_SAMPLERATE; devc->sample_wide = TRUE; - } else if (!strcmp(stropt, opmodes[SR_OP_LOOPBACK_TEST]) && (devc->op_mode != SR_OP_LOOPBACK_TEST)) { - devc->op_mode = SR_OP_LOOPBACK_TEST; + } else if (!strcmp(stropt, opmodes[OP_LPTEST]) && (devc->op_mode != OP_LPTEST)) { + devc->op_mode = OP_LPTEST; + devc->test_mode = SR_TEST_LOOPBACK; devc->stream = FALSE; devc->ch_mode = 0; devc->samplerates_size = 14; @@ -1073,7 +1091,8 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, devc->sample_wide = (devc->cur_samplerate <= DSLOGIC_MAX_DSO_SAMPLERATE); } } else if (sdi->mode == ANALOG) { - devc->op_mode = SR_OP_STREAM; + devc->op_mode = OP_STREAM; + devc->test_mode = SR_TEST_NONE; devc->stream = TRUE; devc->samplerates_size = 10; } @@ -1164,10 +1183,10 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, } sr_dbg("%s: setting Signal Max Height to %d", __func__, devc->max_height); - } else if (id == SR_CONF_EN_CH) { + } else if (id == SR_CONF_PROBE_EN) { ch->enabled = g_variant_get_boolean(data); if (sdi->mode == DSO) { - ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_EN_CH)); + ret = dsl_wr_dso(sdi, dso_cmd_gen(sdi, ch, SR_CONF_PROBE_EN)); uint16_t channel_cnt = 0; GSList *l; for (l = sdi->channels; l; l = l->next) { @@ -1183,7 +1202,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, else sr_dbg("%s: setting ENABLE of channel %d to %d", __func__, ch->index, ch->enabled); - } else if (id == SR_CONF_VPOS) { + } else if (id == SR_CONF_PROBE_VPOS) { ch->vpos = g_variant_get_double(data); sr_dbg("%s: setting VPOS of channel %d to %lf", __func__, ch->index, ch->vpos); @@ -1277,7 +1296,7 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, 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) + else if (devc->test_mode != SR_TEST_NONE) *data = g_variant_new_strv(buffer_ch_modes, 1); else *data = g_variant_new_strv(buffer_ch_modes, ARRAY_SIZE(buffer_ch_modes)); diff --git a/libsigrok4DSL/hardware/demo/demo.c b/libsigrok4DSL/hardware/demo/demo.c index fb4fc3e5..9bb507ab 100644 --- a/libsigrok4DSL/hardware/demo/demo.c +++ b/libsigrok4DSL/hardware/demo/demo.c @@ -111,7 +111,7 @@ struct dev_context { gboolean instant; gboolean data_lock; uint8_t max_height; - uint8_t dso_bits; + uint8_t unit_bits; uint64_t samples_not_sent; uint16_t *buf; @@ -147,6 +147,49 @@ static const int32_t sessions[] = { SR_CONF_PATTERN_MODE, }; +static const int32_t probeOptions[] = { + SR_CONF_PROBE_COUPLING, + SR_CONF_PROBE_VDIV, + SR_CONF_PROBE_MAP_UNIT, + SR_CONF_PROBE_MAP_MIN, + SR_CONF_PROBE_MAP_MAX, +}; + +static const int32_t probeSessions[] = { + SR_CONF_PROBE_COUPLING, + SR_CONF_PROBE_VDIV, + SR_CONF_PROBE_MAP_UNIT, + SR_CONF_PROBE_MAP_MIN, + SR_CONF_PROBE_MAP_MAX, +}; + +static const uint8_t probeCoupling[] = { + SR_DC_COUPLING, + SR_AC_COUPLING, +}; + +static const uint64_t probeVdivs[] = { + SR_mV(10), + SR_mV(20), + SR_mV(50), + SR_mV(100), + SR_mV(200), + SR_mV(500), + SR_V(1), + SR_V(2), +}; + +static const char *probeMapUnits[] = { + "V", + "A", + "°C", + "°F", + "g", + "m", + "m/s", + "Custom", +}; + static const int const_dc = 1.95 / 10 * 255; static const int sinx[] = { 0, 2, 3, 5, 6, 8, 9, 11, 12, 14, 16, 17, 18, 20, 21, 23, 24, 26, 27, 28, @@ -284,7 +327,6 @@ static const char *probe_names[NUM_PROBES + 1] = { "CH8", "CH9", "CH10", "CH11", "CH12", "CH13", "CH14", "CH15", NULL, - }; static const gboolean default_ms_en[] = { @@ -321,6 +363,42 @@ static int hw_init(struct sr_context *sr_ctx) return std_hw_init(sr_ctx, di, LOG_PREFIX); } +static void probe_init(struct sr_dev_inst *sdi) +{ + int i; + GSList *l; + for (l = sdi->channels; l; l = l->next) { + struct sr_channel *probe = (struct sr_channel *)l->data; + probe->vdiv = 1000; + probe->vfactor = 1; + probe->coupling = SR_AC_COUPLING; + probe->trig_value = 0x80; + probe->vpos = (probe->index == 0 ? 0.5 : -0.5)*probe->vdiv; + probe->ms_show = TRUE; + for (i = DSO_MS_BEGIN; i < DSO_MS_END; i++) + probe->ms_en[i] = default_ms_en[i]; + probe->map_unit = probeMapUnits[0]; + probe->map_min = -1; + probe->map_max = 1; + } +} + +static int setup_probes(struct sr_dev_inst *sdi, int num_probes) +{ + uint16_t j; + struct sr_channel *probe; + + for (j = 0; j < num_probes; j++) { + if (!(probe = sr_channel_new(j, (sdi->mode == LOGIC) ? SR_CHANNEL_LOGIC : + ((sdi->mode == DSO) ? SR_CHANNEL_DSO : SR_CHANNEL_ANALOG), + TRUE, probe_names[j]))) + return SR_ERR; + sdi->channels = g_slist_append(sdi->channels, probe); + } + probe_init(sdi); + return SR_OK; +} + static GSList *hw_scan(GSList *options) { struct sr_dev_inst *sdi; @@ -360,7 +438,7 @@ static GSList *hw_scan(GSList *options) devc->timebase = 500; devc->data_lock = FALSE; devc->max_height = 0; - devc->dso_bits = 8; + devc->unit_bits = 8; sdi->priv = devc; @@ -520,25 +598,25 @@ 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: + case SR_CONF_PROBE_VPOS: *data = g_variant_new_double(ch->vpos); break; - case SR_CONF_VDIV: + case SR_CONF_PROBE_VDIV: *data = g_variant_new_uint64(ch->vdiv); break; - case SR_CONF_FACTOR: + case SR_CONF_PROBE_FACTOR: *data = g_variant_new_uint64(ch->vfactor); break; case SR_CONF_TIMEBASE: *data = g_variant_new_uint64(devc->timebase); break; - case SR_CONF_COUPLING: + case SR_CONF_PROBE_COUPLING: *data = g_variant_new_byte(ch->coupling); break; case SR_CONF_TRIGGER_VALUE: *data = g_variant_new_byte(ch->trig_value); break; - case SR_CONF_EN_CH: + case SR_CONF_PROBE_EN: *data = g_variant_new_boolean(ch->enabled); break; case SR_CONF_DATALOCK: @@ -553,8 +631,23 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, case SR_CONF_HW_DEPTH: *data = g_variant_new_uint64(DEMO_MAX_LOGIC_DEPTH); break; - case SR_CONF_DSO_BITS: - *data = g_variant_new_byte(devc->dso_bits); + case SR_CONF_UNIT_BITS: + *data = g_variant_new_byte(devc->unit_bits); + break; + case SR_CONF_PROBE_MAP_UNIT: + if (!sdi || !ch) + return SR_ERR; + *data = g_variant_new_string(ch->map_unit); + break; + case SR_CONF_PROBE_MAP_MIN: + if (!sdi || !ch) + return SR_ERR; + *data = g_variant_new_double(ch->map_min); + break; + case SR_CONF_PROBE_MAP_MAX: + if (!sdi || !ch) + return SR_ERR; + *data = g_variant_new_double(ch->map_max); break; case SR_CONF_VLD_CH_NUM: *data = g_variant_new_int16(NUM_PROBES); @@ -570,10 +663,9 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, struct sr_channel *ch, struct sr_channel_group *cg) { - uint16_t i, j; - int ret; + uint16_t i; + int ret, num_probes; const char *stropt; - struct sr_channel *probe; uint64_t tmp_u64; (void) cg; @@ -611,53 +703,25 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, sdi->mode = g_variant_get_int16(data); ret = SR_OK; if (sdi->mode == LOGIC) { - sr_dev_probes_free(sdi); - for (i = 0; probe_names[i]; i++) { - if (!(probe = sr_channel_new(i, SR_CHANNEL_LOGIC, TRUE, - probe_names[i]))) - ret = SR_ERR; - else - sdi->channels = g_slist_append(sdi->channels, probe); - } + num_probes = ARRAY_SIZE(probe_names) - 1; devc->cur_samplerate = SR_MHZ(1); devc->limit_samples = SR_MB(1); devc->limit_samples_show = devc->limit_samples; } else if (sdi->mode == DSO) { - sr_dev_probes_free(sdi); - for (i = 0; i < DEMO_MAX_DSO_PROBES_NUM; i++) { - if (!(probe = sr_channel_new(i, SR_CHANNEL_DSO, TRUE, - probe_names[i]))) - ret = SR_ERR; - else { - probe->vdiv = 1000; - probe->vfactor = 1; - 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); - probe->ms_show = TRUE; - for (j = DSO_MS_BEGIN; j < DSO_MS_END; j++) - probe->ms_en[j] = default_ms_en[j]; - } - } + num_probes = DEMO_MAX_DSO_PROBES_NUM; devc->cur_samplerate = DEMO_MAX_DSO_SAMPLERATE / DEMO_MAX_DSO_PROBES_NUM; devc->limit_samples = DEMO_MAX_DSO_DEPTH / DEMO_MAX_DSO_PROBES_NUM; devc->limit_samples_show = devc->limit_samples; } else if (sdi->mode == ANALOG) { - sr_dev_probes_free(sdi); - for (i = 0; i < DS_MAX_ANALOG_PROBES_NUM; i++) { - if (!(probe = sr_channel_new(i, SR_CHANNEL_ANALOG, TRUE, - probe_names[i]))) - ret = SR_ERR; - else - sdi->channels = g_slist_append(sdi->channels, probe); - } + num_probes = DS_MAX_ANALOG_PROBES_NUM; devc->cur_samplerate = SR_HZ(100); devc->limit_samples = SR_KB(1); devc->limit_samples_show = devc->limit_samples; } else { - ret = SR_ERR; + num_probes = 0; } + sr_dev_probes_free(sdi); + setup_probes(sdi, num_probes); sr_dbg("%s: setting mode to %d", __func__, sdi->mode); }else if (id == SR_CONF_PATTERN_MODE) { stropt = g_variant_get_string(data, NULL); @@ -699,7 +763,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, ret = SR_OK; } else if (id == SR_CONF_TRIGGER_MARGIN) { ret = SR_OK; - } else if (id == SR_CONF_EN_CH) { + } else if (id == SR_CONF_PROBE_EN) { ch->enabled = g_variant_get_boolean(data); sr_dbg("%s: setting ENABLE of channel %d to %d", __func__, ch->index, ch->enabled); @@ -709,19 +773,19 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, sr_dbg("%s: setting data lock to %d", __func__, devc->data_lock); ret = SR_OK; - } else if (id == SR_CONF_VDIV) { + } else if (id == SR_CONF_PROBE_VDIV) { 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; - } else if (id == SR_CONF_FACTOR) { + } else if (id == SR_CONF_PROBE_FACTOR) { ch->vfactor = g_variant_get_uint64(data); sr_dbg("%s: setting FACTOR of channel %d to %" PRIu64, __func__, ch->index, ch->vfactor); ret = SR_OK; - } else if (id == SR_CONF_VPOS) { + } else if (id == SR_CONF_PROBE_VPOS) { //ch->vpos = g_variant_get_double(data); sr_dbg("%s: setting VPOS of channel %d to %lf", __func__, ch->index, ch->vpos); @@ -731,7 +795,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, sr_dbg("%s: setting TIMEBASE to %" PRIu64, __func__, devc->timebase); ret = SR_OK; - } else if (id == SR_CONF_COUPLING) { + } else if (id == SR_CONF_PROBE_COUPLING) { ch->coupling = g_variant_get_byte(data); sr_dbg("%s: setting AC COUPLING of channel %d to %d", __func__, ch->index, ch->coupling); @@ -751,6 +815,12 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, sr_dbg("%s: setting channel %d Trigger Value to %d", __func__, ch->index, ch->trig_value); ret = SR_OK; + } else if (id == SR_CONF_PROBE_MAP_UNIT) { + ch->map_unit = g_variant_get_string(data, NULL); + } else if (id == SR_CONF_PROBE_MAP_MIN) { + ch->map_min = g_variant_get_double(data); + } else if (id == SR_CONF_PROBE_MAP_MAX) { + ch->map_max = g_variant_get_double(data); } else { ret = SR_ERR_NA; } @@ -806,6 +876,32 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, case SR_CONF_MAX_HEIGHT: *data = g_variant_new_strv(maxHeights, ARRAY_SIZE(maxHeights)); break; + + case SR_CONF_PROBE_CONFIGS: + *data = g_variant_new_from_data(G_VARIANT_TYPE("ai"), + probeOptions, ARRAY_SIZE(probeOptions)*sizeof(int32_t), TRUE, NULL, NULL); + break; + case SR_CONF_PROBE_SESSIONS: + *data = g_variant_new_from_data(G_VARIANT_TYPE("ai"), + probeSessions, ARRAY_SIZE(probeSessions)*sizeof(int32_t), TRUE, NULL, NULL); + break; + case SR_CONF_PROBE_VDIV: + g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}")); + gvar = g_variant_new_from_data(G_VARIANT_TYPE("at"), + probeVdivs, ARRAY_SIZE(probeVdivs)*sizeof(uint64_t), TRUE, NULL, NULL); + g_variant_builder_add(&gvb, "{sv}", "vdivs", gvar); + *data = g_variant_builder_end(&gvb); + break; + case SR_CONF_PROBE_COUPLING: + g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}")); + gvar = g_variant_new_from_data(G_VARIANT_TYPE("ay"), + probeCoupling, ARRAY_SIZE(probeCoupling)*sizeof(uint8_t), TRUE, NULL, NULL); + g_variant_builder_add(&gvb, "{sv}", "coupling", gvar); + *data = g_variant_builder_end(&gvb); + break; + case SR_CONF_PROBE_MAP_UNIT: + *data = g_variant_new_strv(probeMapUnits, ARRAY_SIZE(probeMapUnits)); + break; default: return SR_ERR_NA; } @@ -851,8 +947,8 @@ static void samples_generator(uint16_t *buf, uint64_t size, 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)); +// for (i = 0; i < devc->limit_samples; i++) +// *(buf + i) = *(buf + ((i + size)%devc->limit_samples)); } else if (sdi->mode == LOGIC) { for (i = 0; i < size; i++) { //index = (i/10/g_slist_length(sdi->channels)+start_rand)%len; @@ -871,12 +967,13 @@ static void samples_generator(uint16_t *buf, uint64_t size, } } else if (sdi->mode == ANALOG) { for (i = 0; i < size; i++) { - if (rand() % (devc->limit_samples / 100) == 0) - *(buf + i) = 0x4000 + rand() % 0x8000; - else if (rand() % (devc->limit_samples / 1000) == 0) - *(buf + i) = 0x7000 + rand() % 0x2000; - else - *(buf + i) = 0x8000; + *(buf + i) = 0x8080; + if (i % (int)ceil(size / 7.0)) + *(buf + i) = 0x7E7E + (rand() & 0x0300) + (rand() & 0x003); + else if (rand() > INT_MAX / 4) + *(buf + i) = 0x7878 + (rand() & 0x0F00) + (rand() & 0x00F); + else if (rand() < INT_MAX / 8) + *(buf + i) = 0x6060 + (rand() & 0x3F00) + (rand() & 0x03F); } } else { if (devc->pre_index == 0) { @@ -974,9 +1071,9 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) samples_to_send = MIN(samples_to_send, devc->limit_samples - devc->pre_index); } else if (sdi->mode == ANALOG) { - samples_to_send = ceil(samples_elaspsed * g_slist_length(sdi->channels)); + samples_to_send = ceil(samples_elaspsed/2); samples_to_send = MIN(samples_to_send, - devc->limit_samples * g_slist_length(sdi->channels) - devc->pre_index); + devc->limit_samples - devc->pre_index); } else { samples_to_send = ceil(samples_elaspsed); samples_to_send += devc->samples_not_sent; @@ -1027,7 +1124,7 @@ 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); + devc->samples_counter += sending_now/2; else devc->samples_counter += sending_now; if (sdi->mode == DSO && !devc->instant && @@ -1060,7 +1157,8 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) packet.type = SR_DF_ANALOG; packet.payload = &analog; analog.probes = sdi->channels; - analog.num_samples = sending_now / g_slist_length(sdi->channels); + analog.num_samples = sending_now / 2; + analog.unit_bits = 8; analog.mq = SR_MQ_VOLTAGE; analog.unit = SR_UNIT_VOLT; analog.mqflags = SR_MQFLAG_AC; @@ -1083,7 +1181,7 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) } } - if ((sdi->mode != DSO || devc->instant) && 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); diff --git a/libsigrok4DSL/hwdriver.c b/libsigrok4DSL/hwdriver.c index 6852354c..68f7ea28 100644 --- a/libsigrok4DSL/hwdriver.c +++ b/libsigrok4DSL/hwdriver.c @@ -96,12 +96,6 @@ static struct sr_config_info sr_config_info_data[] = { "Max Height", "Max Height", NULL}, {SR_CONF_FILTER, SR_T_CHAR, "filter", "Filter Targets", "Filter Targets", NULL}, - {SR_CONF_VDIV, SR_T_RATIONAL_VOLT, "vdiv", - "Volts/div", "Volts/div", NULL}, - {SR_CONF_VDIV, SR_T_RATIONAL_VOLT, "factor", - "Probe Factor", "Probe Factor", NULL}, - {SR_CONF_COUPLING, SR_T_CHAR, "coupling", - "Coupling", "Coupling", NULL}, {SR_CONF_DATALOG, SR_T_BOOL, "datalog", "Datalog", "Datalog", NULL}, {SR_CONF_OPERATION_MODE, SR_T_CHAR, "operation", @@ -114,6 +108,19 @@ static struct sr_config_info sr_config_info_data[] = { "Threshold Level", "Threshold Level", NULL}, {SR_CONF_VTH, SR_T_FLOAT, "threshold", "Threshold Level", "Threshold Level", NULL}, + + {SR_CONF_PROBE_COUPLING, SR_T_CHAR, "coupling", + "Coupling", "Coupling", NULL}, + {SR_CONF_PROBE_VDIV, SR_T_RATIONAL_VOLT, "vdiv", + "Volts/div", "Volts/div", NULL}, + {SR_CONF_PROBE_FACTOR, SR_T_UINT64, "factor", + "Probe Factor", "Probe Factor", NULL}, + {SR_CONF_PROBE_MAP_UNIT, SR_T_CHAR, "munit", + "Map Unit", "Map Unit", NULL}, + {SR_CONF_PROBE_MAP_MIN, SR_T_FLOAT, "MMIN", + "Map Min", "Map Min", NULL}, + {SR_CONF_PROBE_MAP_MAX, SR_T_FLOAT, "MMAX", + "Map Max", "Map Max", NULL}, {0, 0, NULL, NULL, NULL, NULL}, }; diff --git a/libsigrok4DSL/libsigrok.h b/libsigrok4DSL/libsigrok.h index 030494c2..eab601e5 100644 --- a/libsigrok4DSL/libsigrok.h +++ b/libsigrok4DSL/libsigrok.h @@ -94,8 +94,13 @@ enum { #define SR_MB(n) ((n) * (uint64_t)(1048576ULL)) #define SR_GB(n) ((n) * (uint64_t)(1073741824ULL)) +#define SR_mV(n) (n) +#define SR_V(n) ((n) * (uint64_t)(1000ULL)) +#define SR_KV(n) ((n) * (uint64_t)(1000000ULL)) +#define SR_MV(n) ((n) * (uint64_t)(1000000000ULL)) + #define SR_MAX_PROBENAME_LEN 32 -#define DS_MAX_ANALOG_PROBES_NUM 8 +#define DS_MAX_ANALOG_PROBES_NUM 4 #define DS_MAX_DSO_PROBES_NUM 2 #define TriggerStages 16 #define TriggerProbes 16 @@ -362,6 +367,10 @@ struct sr_datafeed_analog { /** The probes for which data is included in this packet. */ GSList *probes; int num_samples; + /** How many bits for each sample */ + uint8_t unit_bits; + /** Interval between two valid samples */ + uint16_t unit_pitch; /** Measured quantity (voltage, current, temperature, and so on). */ int mq; /** Unit in which the MQ is measured. */ @@ -603,6 +612,9 @@ struct sr_channel { int8_t comb_diff_bom; gboolean ms_show; gboolean ms_en[DSO_MS_END - DSO_MS_BEGIN]; + const char *map_unit; + double map_min; + double map_max; }; /** Structure for groups of channels that have common properties. */ @@ -779,8 +791,8 @@ enum { /** DSO configure sync */ SR_CONF_DSO_SYNC, - /** DSO vertical resolution */ - SR_CONF_DSO_BITS, + /** How many bits for each sample */ + SR_CONF_UNIT_BITS, /** Valid channel number */ SR_CONF_VLD_CH_NUM, @@ -810,33 +822,17 @@ enum { SR_CONF_TEST, SR_CONF_EEPROM, - /** Volts/div for dso channel. */ - SR_CONF_VDIV, - /** Vertical position */ - SR_CONF_VPOS, - /** Vertical offset */ - SR_CONF_VOFF, - SR_CONF_VOFF_DEFAULT, - SR_CONF_VOFF_RANGE, - /** VGain */ - SR_CONF_VGAIN, - SR_CONF_VGAIN_DEFAULT, - SR_CONF_VGAIN_RANGE, - /** Coupling for dso channel. */ - SR_CONF_COUPLING, - /** Channel enable for dso channel. */ - SR_CONF_EN_CH, + /** Data lock */ SR_CONF_DATALOCK, - /** probe factor for dso channel. */ - SR_CONF_FACTOR, + /** Trigger types. */ SR_CONF_TRIGGER_TYPE, @@ -847,7 +843,7 @@ enum { /** Number of timebases, as related to SR_CONF_TIMEBASE. */ SR_CONF_NUM_TIMEBASE, - /** Number of vertical divisions, as related to SR_CONF_VDIV. */ + /** Number of vertical divisions, as related to SR_CONF_PROBE_VDIV. */ SR_CONF_NUM_VDIV, /** clock type (internal/external) */ @@ -878,6 +874,43 @@ enum { SR_CONF_MAX_DSO_SAMPLELIMITS, SR_CONF_HW_DEPTH, + /*--- Probe configuration -------------------------------------------*/ + /** Probe options */ + SR_CONF_PROBE_CONFIGS, + + /** Probe options */ + SR_CONF_PROBE_SESSIONS, + + /** Enable */ + SR_CONF_PROBE_EN, + + /** Coupling */ + SR_CONF_PROBE_COUPLING, + + /** Volts/div */ + SR_CONF_PROBE_VDIV, + + /** Factor */ + SR_CONF_PROBE_FACTOR, + + /** Vertical position */ + SR_CONF_PROBE_VPOS, + + /** Mapping */ + SR_CONF_PROBE_MAP_UNIT, + SR_CONF_PROBE_MAP_MIN, + SR_CONF_PROBE_MAP_MAX, + + /** Vertical offset */ + SR_CONF_PROBE_VOFF, + SR_CONF_PROBE_VOFF_DEFAULT, + SR_CONF_PROBE_VOFF_RANGE, + + /** VGain */ + SR_CONF_PROBE_VGAIN, + SR_CONF_PROBE_VGAIN_DEFAULT, + SR_CONF_PROBE_VGAIN_RANGE, + /*--- Special stuff -------------------------------------------------*/ /** Scan options supported by the driver. */ @@ -1003,17 +1036,16 @@ enum { SR_ST_STOPPING, }; -/** Device operation modes. */ +/** Device test modes. */ enum { - /** Normal */ - SR_OP_BUFFER = 0, - SR_OP_STREAM = 1, + /** No test mode */ + SR_TEST_NONE, /** Internal pattern test mode */ - SR_OP_INTERNAL_TEST = 2, + SR_TEST_INTERNAL, /** External pattern test mode */ - SR_OP_EXTERNAL_TEST = 3, + SR_TEST_EXTERNAL, /** SDRAM loopback test mode */ - SR_OP_LOOPBACK_TEST = 4, + SR_TEST_LOOPBACK, }; /** Device buffer mode */ diff --git a/libsigrok4DSL/session_driver.c b/libsigrok4DSL/session_driver.c index de49d826..7eabd173 100644 --- a/libsigrok4DSL/session_driver.c +++ b/libsigrok4DSL/session_driver.c @@ -74,7 +74,7 @@ struct session_vdev { int num_probes; int enabled_probes; uint64_t timebase; - uint8_t bits; + uint8_t unit_bits; uint8_t max_height; struct sr_status mstatus; }; @@ -202,6 +202,7 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *cb_sdi) packet.payload = &analog; analog.probes = sdi->channels; analog.num_samples = ret / vdev->num_probes; + analog.unit_bits = vdev->unit_bits; analog.mq = SR_MQ_VOLTAGE; analog.unit = SR_UNIT_VOLT; analog.mqflags = SR_MQFLAG_AC; @@ -298,7 +299,12 @@ static int dev_open(struct sr_dev_inst *sdi) vdev->cur_channel = 0; vdev->file_opened = FALSE; vdev->num_blocks = 0; - vdev->bits = 8; + if (sdi->mode == DSO) + vdev->unit_bits = 8; + else if (sdi->mode == ANALOG) + vdev->unit_bits = 16; + else + vdev->unit_bits = 1; vdev->max_height = 0; dev_insts = g_slist_append(dev_insts, sdi); @@ -358,38 +364,38 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, } else return SR_ERR; break; - case SR_CONF_DSO_BITS: + case SR_CONF_UNIT_BITS: if (sdi) { vdev = sdi->priv; - *data = g_variant_new_byte(vdev->bits); + *data = g_variant_new_byte(vdev->unit_bits); } else return SR_ERR; break; - case SR_CONF_EN_CH: + case SR_CONF_PROBE_EN: if (sdi && ch) { *data = g_variant_new_boolean(ch->enabled); } else return SR_ERR; break; - case SR_CONF_COUPLING: + case SR_CONF_PROBE_COUPLING: if (sdi && ch) { *data = g_variant_new_byte(ch->coupling); } else return SR_ERR; break; - case SR_CONF_VDIV: + case SR_CONF_PROBE_VDIV: if (sdi && ch) { *data = g_variant_new_uint64(ch->vdiv); } else return SR_ERR; break; - case SR_CONF_FACTOR: + case SR_CONF_PROBE_FACTOR: if (sdi && ch) { *data = g_variant_new_uint64(ch->vfactor); } else return SR_ERR; break; - case SR_CONF_VPOS: + case SR_CONF_PROBE_VPOS: if (sdi && ch) { *data = g_variant_new_double(ch->vpos); } else @@ -472,9 +478,9 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, vdev->timebase = g_variant_get_uint64(data); sr_info("Setting timebase to %" PRIu64 ".", vdev->timebase); break; - case SR_CONF_DSO_BITS: - vdev->bits = g_variant_get_byte(data); - sr_info("Setting DSO bits to %d.", vdev->bits); + case SR_CONF_UNIT_BITS: + vdev->unit_bits = g_variant_get_byte(data); + sr_info("Setting unit bits to %d.", vdev->unit_bits); break; case SR_CONF_SESSIONFILE: vdev->sessionfile = g_strdup(g_variant_get_bytestring(data)); @@ -513,19 +519,19 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, } } break; - case SR_CONF_EN_CH: + case SR_CONF_PROBE_EN: ch->enabled = g_variant_get_boolean(data); break; - case SR_CONF_COUPLING: + case SR_CONF_PROBE_COUPLING: ch->coupling = g_variant_get_byte(data); break; - case SR_CONF_VDIV: + case SR_CONF_PROBE_VDIV: ch->vdiv = g_variant_get_uint64(data); break; - case SR_CONF_FACTOR: + case SR_CONF_PROBE_FACTOR: ch->vfactor = g_variant_get_uint64(data); break; - case SR_CONF_VPOS: + case SR_CONF_PROBE_VPOS: ch->vpos = g_variant_get_double(data); break; case SR_CONF_TRIGGER_VALUE: diff --git a/libsigrok4DSL/session_file.c b/libsigrok4DSL/session_file.c index 2de9e444..ecfa36c6 100644 --- a/libsigrok4DSL/session_file.c +++ b/libsigrok4DSL/session_file.c @@ -217,7 +217,7 @@ SR_API int sr_session_load(const char *filename) g_variant_new_uint64(tmp_u64), sdi, NULL, NULL); } else if (!strcmp(keys[j], "bits")) { tmp_u64 = strtoull(val, NULL, 10); - sdi->driver->config_set(SR_CONF_DSO_BITS, + sdi->driver->config_set(SR_CONF_UNIT_BITS, g_variant_new_byte(tmp_u64), sdi, NULL, NULL); } else if (!strcmp(keys[j], "trigger time")) { tmp_64 = strtoll(val, NULL, 10); @@ -271,7 +271,7 @@ SR_API int sr_session_load(const char *filename) 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, + sdi->driver->config_set(SR_CONF_PROBE_EN, g_variant_new_boolean(tmp_u64), sdi, probe, NULL); } } else if (!strncmp(keys[j], "coupling", 8)) { @@ -279,7 +279,7 @@ SR_API int sr_session_load(const char *filename) 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, + sdi->driver->config_set(SR_CONF_PROBE_COUPLING, g_variant_new_byte(tmp_u64), sdi, probe, NULL); } } else if (!strncmp(keys[j], "vDiv", 4)) { @@ -287,7 +287,7 @@ SR_API int sr_session_load(const char *filename) 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, + sdi->driver->config_set(SR_CONF_PROBE_VDIV, g_variant_new_uint64(tmp_u64), sdi, probe, NULL); } } else if (!strncmp(keys[j], "vFactor", 7)) { @@ -295,7 +295,7 @@ SR_API int sr_session_load(const char *filename) 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, + sdi->driver->config_set(SR_CONF_PROBE_FACTOR, g_variant_new_uint64(tmp_u64), sdi, probe, NULL); } } else if (!strncmp(keys[j], "vPos", 4)) { @@ -303,7 +303,7 @@ SR_API int sr_session_load(const char *filename) 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, + sdi->driver->config_set(SR_CONF_PROBE_VPOS, g_variant_new_double(tmp_double), sdi, probe, NULL); } } else if (!strncmp(keys[j], "vTrig", 5)) {