Commit fd7c9cd1 authored by DreamSourceLab's avatar DreamSourceLab
Browse files

Add DAQ mode for DSCope series of products

parent dcdd51b2
......@@ -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<boost::recursive_mutex> 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;
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);
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 * 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
......@@ -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;
};
......
......@@ -93,6 +93,26 @@ uint64_t Snapshot::get_sample_count() const
return _sample_count;
}
uint64_t Snapshot::get_ring_start() const
{
boost::lock_guard<boost::recursive_mutex> 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<boost::recursive_mutex> 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;
......
......@@ -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;
......
......@@ -107,17 +107,17 @@ void Calibration::set_device(boost::shared_ptr<device::DevInst> 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<device::DevInst> 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);
......
File mode changed from 100755 to 100644
......@@ -24,8 +24,9 @@
#include <boost/foreach.hpp>
#include <QFormLayout>
#include <QListWidget>
#include <QSpinBox>
#include <QDoubleSpinBox>
#include "dsmessagebox.h"
#include <pv/prop/property.h>
......@@ -47,20 +48,10 @@ DeviceOptions::DeviceOptions(QWidget *parent, boost::shared_ptr<pv::device::DevI
_props_box->setLayout(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<pv::prop::Property> > &properties =
const vector< boost::shared_ptr<pv::prop::Property> > &dev_props =
_device_options_binding.properties();
BOOST_FOREACH(boost::shared_ptr<pv::prop::Property> p, properties) {
BOOST_FOREACH(boost::shared_ptr<pv::prop::Property> 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<pv::prop::binding::ProbeOptions *>::iterator i = _probe_options_binding_list.begin();
while(i != _probe_options_binding_list.end()) {
const vector< boost::shared_ptr<pv::prop::Property> > &probe_props =
(*i)->properties();
BOOST_FOREACH(boost::shared_ptr<pv::prop::Property> 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; i<num_opts; i++){
QRadioButton *ch_opts = new QRadioButton(options[i]);
_probes_box_layout.addWidget(ch_opts, row0, col, 1, 8);
layout.addWidget(ch_opts, row0, col, 1, 8);
connect(ch_opts, SIGNAL(pressed()), this, SLOT(channel_check()));
row0++;
if (QString::fromUtf8(options[i]) == ch_mode)
......@@ -215,8 +218,8 @@ void DeviceOptions::setup_probes()
QLabel *probe_label = new QLabel(QString::number(probe->index), this);
QCheckBox *probe_checkBox = new QCheckBox(this);
probe_checkBox->setCheckState(probe->enabled ? Qt::Checked : Qt::Unchecked);
_probes_box_layout.addWidget(probe_label, 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<QRadioButton*>(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<QCheckBox*>(sender());
if (sc == NULL || !sc->isChecked())
return;
if (_dev_inst->dev_inst()->mode == LOGIC) {
QCheckBox* sc=dynamic_cast<QCheckBox*>(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<QCheckBox *>::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<QCheckBox *>::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<QCheckBox*>(sender());
if (sc != NULL) {
QGridLayout *const layout = (QGridLayout *)sc->property("Layout").value<void *>();
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);
}
}
}
gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_VLD_CH_NUM);
if (gvar == NULL)
return;
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()));
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();
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;
sc->setChecked(false);
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<pv::prop::Property> > &properties =
probe_options_binding->properties();
int i = 1;
BOOST_FOREACH(boost::shared_ptr<pv::prop::Property> 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));
}
layout.addWidget(tabWidget, 0, 0, 1, 1);
}
} // namespace dialogs
......
......@@ -43,6 +43,7 @@
#include <libsigrok4DSL/libsigrok.h>
#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 <QLabel *> _probes_label_list;
QVector <QCheckBox *> _probes_checkBox_list;
QVector <QWidget *> _probe_widget_list;
QGroupBox *_props_box;
......@@ -98,6 +101,7 @@ private:
QString _mode;
pv::prop::binding::DeviceOptions _device_options_binding;
QVector <pv::prop::binding::ProbeOptions *> _probe_options_binding_list;
};
} // namespace dialogs
......
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
......@@ -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<view::AnalogSignal> analogSig;
if (analogSig = dynamic_pointer_cast<view::AnalogSignal>(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<view::AnalogSignal> analogSig;
if (analogSig = dynamic_pointer_cast<view::AnalogSignal>(s)) {
s_obj["vdiv"] = QJsonValue::fromVariant(static_cast<qulonglong>(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;
......
......@@ -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:
......
/*
* This file is part of the DSView project.
* DSView is based on PulseView.
*
* Copyright (C) 2018 DreamSourceLab <support@dreamsourcelab.com>
*
* 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 <boost/bind.hpp>
#include <QDebug>
#include <QObject>
#include <stdint.h>
#include "probeoptions.h"
#include <pv/prop/bool.h>
#include <pv/prop/double.h>
#include <pv/prop/enum.h>
#include <pv/prop/int.h>
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<double, double>(-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<Property>(
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<QString (GVariant*)> printer)
{
GVariant *gvar;
GVariantIter iter;
vector< pair<GVariant*, QString> > 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<Property>(
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<int64_t, int64_t> > range)
{
_properties.push_back(boost::shared_ptr<Property>(
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<double, double> > range,
int decimals, boost::optional<double> step)
{
_properties.push_back(boost::shared_ptr<Property>(
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
/*
* This file is part of the DSView project.
* DSView is based on PulseView.
*
* Copyright (C) 2018 DreamSourceLab <support@dreamsourcelab.com>
*
* 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 <boost/function.hpp>
#include <boost/optional.hpp>
#include <QString>
#include <libsigrok4DSL/libsigrok.h>
#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<QString (GVariant*)> printer = print_gvariant);
void bind_int(const QString &name, int key, QString suffix,
boost::optional< std::pair<int64_t, int64_t> > range);
void bind_double(const QString &name, int key, QString suffix,
boost::optional<std::pair<double, double> > range,
int decimals, boost::optional<double> 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
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment