Merge branch 'improve_dso_display' into develop

This commit is contained in:
DreamSourceLab 2015-05-03 18:40:52 +08:00
commit c2724b765c
20 changed files with 537 additions and 199 deletions

View File

@ -90,6 +90,7 @@ DeviceOptions::DeviceOptions(struct sr_dev_inst *sdi) :
case SR_CONF_STREAM:
case SR_CONF_TEST:
case SR_CONF_STATUS:
case SR_CONF_FACTOR:
bind_enum(name, key, gvar_list);
break;

View File

@ -60,18 +60,21 @@
#include <boost/foreach.hpp>
using boost::dynamic_pointer_cast;
using boost::function;
using boost::lock_guard;
using boost::mutex;
using boost::shared_ptr;
using std::list;
using std::map;
using std::set;
using std::string;
using std::vector;
using std::deque;
using std::min;
//using boost::dynamic_pointer_cast;
//using boost::function;
//using boost::lock_guard;
//using boost::mutex;
//using boost::shared_ptr;
//using std::list;
//using std::map;
//using std::set;
//using std::string;
//using std::vector;
//using std::deque;
//using std::min;
using namespace boost;
using namespace std;
namespace pv {
@ -100,10 +103,6 @@ SigSession::SigSession(DeviceManager &device_manager) :
SigSession::~SigSession()
{
stop_capture();
if (_hotplug_handle) {
stop_hotplug_proc();
deregister_hotplug_callback();
}
ds_trigger_destroy();
@ -111,6 +110,11 @@ SigSession::~SigSession()
// TODO: This should not be necessary
_session = NULL;
if (_hotplug_handle) {
stop_hotplug_proc();
deregister_hotplug_callback();
}
}
boost::shared_ptr<device::DevInst> SigSession::get_device() const
@ -118,7 +122,7 @@ boost::shared_ptr<device::DevInst> SigSession::get_device() const
return _dev_inst;
}
void SigSession::set_device(shared_ptr<device::DevInst> dev_inst) throw(QString)
void SigSession::set_device(boost::shared_ptr<device::DevInst> dev_inst) throw(QString)
{
using pv::device::Device;
@ -154,13 +158,13 @@ void SigSession::set_file(const string &name) throw(QString)
// Deslect the old device, because file type detection in File::create
// destorys the old session inside libsigrok.
try {
set_device(shared_ptr<device::DevInst>());
set_device(boost::shared_ptr<device::DevInst>());
} catch(const QString e) {
throw(e);
return;
}
try {
set_device(shared_ptr<device::DevInst>(device::File::create(name)));
set_device(boost::shared_ptr<device::DevInst>(device::File::create(name)));
} catch(const QString e) {
throw(e);
return;
@ -342,8 +346,8 @@ void SigSession::export_file(const std::string &name, QWidget* parent, const std
void SigSession::set_default_device(boost::function<void (const QString)> error_handler)
{
shared_ptr<pv::device::DevInst> default_device;
const list< shared_ptr<device::DevInst> > &devices =
boost::shared_ptr<pv::device::DevInst> default_device;
const list<boost::shared_ptr<device::DevInst> > &devices =
_device_manager.devices();
if (!devices.empty()) {
@ -351,7 +355,7 @@ void SigSession::set_default_device(boost::function<void (const QString)> error_
default_device = devices.front();
// Try and find the DreamSourceLab device and select that by default
BOOST_FOREACH (shared_ptr<pv::device::DevInst> dev, devices)
BOOST_FOREACH (boost::shared_ptr<pv::device::DevInst> dev, devices)
if (dev->dev_inst() &&
strcmp(dev->dev_inst()->driver->name,
"demo") != 0) {
@ -373,7 +377,7 @@ void SigSession::release_device(device::DevInst *dev_inst)
assert(_dev_inst.get() == dev_inst);
assert(_capture_state != Running);
_dev_inst = shared_ptr<device::DevInst>();
_dev_inst = boost::shared_ptr<device::DevInst>();
//_dev_inst.reset();
}
@ -447,11 +451,11 @@ vector< boost::shared_ptr<view::GroupSignal> > SigSession::get_group_signals()
return _group_traces;
}
set< shared_ptr<data::SignalData> > SigSession::get_data() const
set< boost::shared_ptr<data::SignalData> > SigSession::get_data() const
{
lock_guard<mutex> lock(_signals_mutex);
set< shared_ptr<data::SignalData> > data;
BOOST_FOREACH(const shared_ptr<view::Signal> sig, _signals) {
set< boost::shared_ptr<data::SignalData> > data;
BOOST_FOREACH(const boost::shared_ptr<view::Signal> sig, _signals) {
assert(sig);
data.insert(sig->data());
}
@ -513,7 +517,7 @@ void SigSession::set_capture_state(capture_state state)
capture_state_changed(state);
}
void SigSession::sample_thread_proc(shared_ptr<device::DevInst> dev_inst,
void SigSession::sample_thread_proc(boost::shared_ptr<device::DevInst> dev_inst,
boost::function<void (const QString)> error_handler)
{
assert(dev_inst);
@ -577,8 +581,8 @@ void SigSession::read_sample_rate(const sr_dev_inst *const sdi)
}
// Set the sample rate of all data
const set< shared_ptr<data::SignalData> > data_set = get_data();
BOOST_FOREACH(shared_ptr<data::SignalData> data, data_set) {
const set< boost::shared_ptr<data::SignalData> > data_set = get_data();
BOOST_FOREACH(boost::shared_ptr<data::SignalData> data, data_set) {
assert(data);
data->set_samplerate(sample_rate);
}
@ -737,13 +741,13 @@ void SigSession::init_signals()
break;
case SR_CHANNEL_DSO:
signal = shared_ptr<view::Signal>(
signal = boost::shared_ptr<view::Signal>(
new view::DsoSignal(_dev_inst, _dso_data, probe));
break;
case SR_CHANNEL_ANALOG:
if (probe->enabled)
signal = shared_ptr<view::Signal>(
signal = boost::shared_ptr<view::Signal>(
new view::AnalogSignal(_dev_inst, _analog_data, probe));
break;
}
@ -781,13 +785,13 @@ void SigSession::reload()
break;
case SR_CHANNEL_DSO:
signal = shared_ptr<view::Signal>(
signal = boost::shared_ptr<view::Signal>(
new view::DsoSignal(_dev_inst,_dso_data, probe));
break;
case SR_CHANNEL_ANALOG:
if (probe->enabled)
signal = shared_ptr<view::Signal>(
signal = boost::shared_ptr<view::Signal>(
new view::AnalogSignal(_dev_inst, _analog_data, probe));
break;
}
@ -879,7 +883,7 @@ void SigSession::feed_in_logic(const sr_datafeed_logic &logic)
return;
}
receive_data(logic.length/logic.unitsize);
emit receive_data(logic.length/logic.unitsize);
data_received();
//data_updated();
}
@ -1005,7 +1009,7 @@ void SigSession::data_feed_in(const struct sr_dev_inst *sdi,
_cur_analog_snapshot.reset();
}
#ifdef ENABLE_DECODE
for (vector< shared_ptr<view::DecodeTrace> >::iterator i =
for (vector< boost::shared_ptr<view::DecodeTrace> >::iterator i =
_decode_traces.begin();
i != _decode_traces.end();
i++)
@ -1138,7 +1142,7 @@ uint16_t SigSession::get_ch_num(int type)
uint16_t dso_ch_num = 0;
uint16_t analog_ch_num = 0;
if (_dev_inst->dev_inst()) {
BOOST_FOREACH(const shared_ptr<view::Signal> s, _signals)
BOOST_FOREACH(const boost::shared_ptr<view::Signal> s, _signals)
{
assert(s);
if (dynamic_pointer_cast<view::LogicSignal>(s) && s->enabled()) {
@ -1174,15 +1178,15 @@ uint16_t SigSession::get_ch_num(int type)
bool SigSession::add_decoder(srd_decoder *const dec)
{
bool ret = false;
map<const srd_channel*, shared_ptr<view::LogicSignal> > probes;
shared_ptr<data::DecoderStack> decoder_stack;
map<const srd_channel*, boost::shared_ptr<view::LogicSignal> > probes;
boost::shared_ptr<data::DecoderStack> decoder_stack;
try
{
//lock_guard<mutex> lock(_signals_mutex);
// Create the decoder
decoder_stack = shared_ptr<data::DecoderStack>(
decoder_stack = boost::shared_ptr<data::DecoderStack>(
new data::DecoderStack(*this, dec));
// Make a list of all the probes
@ -1198,7 +1202,7 @@ bool SigSession::add_decoder(srd_decoder *const dec)
decoder_stack->stack().front()->set_probes(probes);
// Create the decode signal
shared_ptr<view::DecodeTrace> d(
boost::shared_ptr<view::DecodeTrace> d(
new view::DecodeTrace(*this, decoder_stack,
_decode_traces.size()));
if (d->create_popup()) {
@ -1221,7 +1225,7 @@ bool SigSession::add_decoder(srd_decoder *const dec)
return ret;
}
vector< shared_ptr<view::DecodeTrace> > SigSession::get_decode_signals() const
vector< boost::shared_ptr<view::DecodeTrace> > SigSession::get_decode_signals() const
{
lock_guard<mutex> lock(_signals_mutex);
return _decode_traces;
@ -1229,7 +1233,7 @@ vector< shared_ptr<view::DecodeTrace> > SigSession::get_decode_signals() const
void SigSession::remove_decode_signal(view::DecodeTrace *signal)
{
for (vector< shared_ptr<view::DecodeTrace> >::iterator i =
for (vector< boost::shared_ptr<view::DecodeTrace> >::iterator i =
_decode_traces.begin();
i != _decode_traces.end();
i++)
@ -1244,7 +1248,7 @@ void SigSession::remove_decode_signal(view::DecodeTrace *signal)
void SigSession::remove_decode_signal(int index)
{
int cur_index = 0;
for (vector< shared_ptr<view::DecodeTrace> >::iterator i =
for (vector< boost::shared_ptr<view::DecodeTrace> >::iterator i =
_decode_traces.begin();
i != _decode_traces.end();
i++)
@ -1262,7 +1266,7 @@ void SigSession::remove_decode_signal(int index)
void SigSession::rst_decoder(int index)
{
int cur_index = 0;
for (vector< shared_ptr<view::DecodeTrace> >::iterator i =
for (vector< boost::shared_ptr<view::DecodeTrace> >::iterator i =
_decode_traces.begin();
i != _decode_traces.end();
i++)
@ -1283,7 +1287,7 @@ void SigSession::rst_decoder(int index)
void SigSession::rst_decoder(view::DecodeTrace *signal)
{
for (vector< shared_ptr<view::DecodeTrace> >::iterator i =
for (vector< boost::shared_ptr<view::DecodeTrace> >::iterator i =
_decode_traces.begin();
i != _decode_traces.end();
i++)

View File

@ -35,6 +35,7 @@
#include <set>
#include <string>
#include <vector>
#include <stdint.h>
#include <QObject>
#include <QString>

View File

@ -5,12 +5,12 @@
namespace pv {
namespace view {
dslDial::dslDial(const quint64 div, const quint64 step,
const QVector<quint64> value, const QVector<QString> unit)
dslDial::dslDial(const uint64_t div, const uint64_t step,
const QVector<uint64_t> value, const QVector<QString> unit)
{
assert(div > 0);
assert(step > 0);
assert((quint64)value.count() == div);
assert((uint64_t)value.count() == div);
assert(unit.count() > 0);
_div = div;
@ -18,6 +18,7 @@ dslDial::dslDial(const quint64 div, const quint64 step,
_value = value;
_unit = unit;
_sel = 0;
_factor = 1;
}
dslDial::~dslDial()
@ -39,11 +40,11 @@ void dslDial::paint(QPainter &p, QRectF dialRect, QColor dialColor)
p.save();
p.translate(dialRect.center());
p.rotate(45);
for (quint64 i = 0; i < _div; i++) {
for (uint64_t i = 0; i < _div; i++) {
// draw major ticks
p.drawLine(0, dialRect.width()/2+3, 0, dialRect.width()/2+8);
// draw minor ticks
for (quint64 j = 0; (j < 5) && (i < _div - 1); j++) {
for (uint64_t j = 0; (j < 5) && (i < _div - 1); j++) {
p.drawLine(0, dialRect.width()/2+3, 0, dialRect.width()/2+5);
p.rotate(54.0/(_div-1));
}
@ -55,8 +56,8 @@ void dslDial::paint(QPainter &p, QRectF dialRect, QColor dialColor)
p.drawLine(-3, 0, 0, dialRect.width()/2-3);
p.restore();
// draw value
quint64 displayValue = _value[_sel];
quint64 displayIndex = 0;
uint64_t displayValue = _value[_sel]*_factor;
uint64_t displayIndex = 0;
while(displayValue / _step >= 1) {
displayValue = displayValue / _step;
displayIndex++;
@ -67,14 +68,14 @@ void dslDial::paint(QPainter &p, QRectF dialRect, QColor dialColor)
}
void dslDial::set_sel(quint64 sel)
void dslDial::set_sel(uint64_t sel)
{
assert(sel < _div);
_sel = sel;
}
quint64 dslDial::get_sel()
uint64_t dslDial::get_sel()
{
return _sel;
}
@ -95,16 +96,28 @@ bool dslDial::isMax()
return false;
}
quint64 dslDial::get_value()
uint64_t dslDial::get_value()
{
return _value[_sel];
}
bool dslDial::set_value(quint64 value)
bool dslDial::set_value(uint64_t value)
{
assert(_value.contains(value));
_sel = _value.indexOf(value, 0);
}
void dslDial::set_factor(uint64_t factor)
{
if (_factor != factor) {
_factor = factor;
}
}
uint64_t dslDial::get_factor()
{
return _factor;
}
} // namespace view
} // namespace pv

View File

@ -10,8 +10,8 @@ namespace view {
class dslDial
{
public:
dslDial(const quint64 div, const quint64 step,
const QVector<quint64> value, const QVector<QString> unit);
dslDial(const uint64_t div, const uint64_t step,
const QVector<uint64_t> value, const QVector<QString> unit);
virtual ~dslDial();
public:
@ -23,23 +23,28 @@ public:
void paint(QPainter &p, QRectF dialRect, QColor dialColor);
// set/get current select
void set_sel(quint64 sel);
quint64 get_sel();
void set_sel(uint64_t sel);
uint64_t get_sel();
// boundary detection
bool isMin();
bool isMax();
// get current value
quint64 get_value();
bool set_value(quint64 value);
uint64_t get_value();
bool set_value(uint64_t value);
// set/get factor
void set_factor(uint64_t factor);
uint64_t get_factor();
private:
quint64 _div;
quint64 _step;
QVector<quint64> _value;
uint64_t _div;
uint64_t _step;
QVector<uint64_t> _value;
QVector<QString> _unit;
quint64 _sel;
uint64_t _sel;
uint64_t _factor;
};
} // namespace view

View File

@ -120,21 +120,26 @@ DsoSignal::DsoSignal(boost::shared_ptr<pv::device::DevInst> dev_inst,
//_zeroPos(probe->index * 0.5 + 0.25)
_trig_vpos(0.5),
_zeroPos(0.5),
_zero_off(255/2.0),
_autoV(false),
_autoH(false)
_autoH(false),
_hover_en(false),
_hover_index(0),
_hover_point(QPointF(0, 0)),
_hover_value(0)
{
QVector<quint64> vValue;
QVector<uint64_t> vValue;
QVector<QString> vUnit;
QVector<quint64> hValue;
QVector<uint64_t> hValue;
QVector<QString> hUnit;
for(quint64 i = 0; i < vDialValueCount; i++)
for(uint64_t i = 0; i < vDialValueCount; i++)
vValue.append(vDialValue[i]);
for(quint64 i = 0; i < vDialUnitCount; i++)
for(uint64_t i = 0; i < vDialUnitCount; i++)
vUnit.append(vDialUnit[i]);
for(quint64 i = 0; i < hDialValueCount; i++)
for(uint64_t i = 0; i < hDialValueCount; i++)
hValue.append(hDialValue[i]);
for(quint64 i = 0; i < hDialUnitCount; i++)
for(uint64_t i = 0; i < hDialUnitCount; i++)
hUnit.append(hDialUnit[i]);
_vDial = new dslDial(vDialValueCount, vDialValueStep, vValue, vUnit);
@ -244,10 +249,15 @@ void DsoSignal::set_vDialActive(bool active)
bool DsoSignal::go_vDialPre()
{
if (enabled() && !_vDial->isMin()) {
const double pre_vdiv = _vDial->get_value();
_vDial->set_sel(_vDial->get_sel() - 1);
_dev_inst->set_config(_probe, NULL, SR_CONF_VDIV,
g_variant_new_uint64(_vDial->get_value()));
if (_view->session().get_capture_state() == SigSession::Stopped)
_scale *= pre_vdiv/_vDial->get_value();
update_zeroPos();
_view->set_need_update(true);
_view->update();
return true;
} else {
_autoV = false;
@ -258,10 +268,15 @@ bool DsoSignal::go_vDialPre()
bool DsoSignal::go_vDialNext()
{
if (enabled() && !_vDial->isMax()) {
const double pre_vdiv = _vDial->get_value();
_vDial->set_sel(_vDial->get_sel() + 1);
_dev_inst->set_config(_probe, NULL, SR_CONF_VDIV,
g_variant_new_uint64(_vDial->get_value()));
if (_view->session().get_capture_state() == SigSession::Stopped)
_scale *= pre_vdiv/_vDial->get_value();
update_zeroPos();
_view->set_need_update(true);
_view->update();
return true;
} else {
_autoV = false;
@ -482,6 +497,29 @@ void DsoSignal::set_zeroPos(int pos)
}
}
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);
if (gvar != NULL) {
prefactor = g_variant_get_uint64(gvar);
g_variant_unref(gvar);
} else {
qDebug() << "ERROR: config_get SR_CONF_FACTOR failed.";
return;
}
if (prefactor != factor) {
_dev_inst->set_config(_probe, NULL, SR_CONF_FACTOR,
g_variant_new_uint64(factor));
_vDial->set_factor(factor);
_view->set_need_update(true);
_view->update();
}
}
}
void DsoSignal::update_zeroPos()
{
if (strcmp(_dev_inst->dev_inst()->driver->name, "DSCope") == 0) {
@ -505,7 +543,7 @@ void DsoSignal::paint_back(QPainter &p, int left, int right)
assert(_view);
int i, j;
const int height = _view->viewport()->height() - UpMargin - DownMargin;
const int height = get_view_rect().height();
const int width = right - left;
p.setPen(Qt::NoPen);
@ -568,7 +606,7 @@ void DsoSignal::paint_mid(QPainter &p, int left, int right)
assert(right >= left);
if (enabled()) {
const int height = _view->viewport()->height() - UpMargin - DownMargin;
const int height = get_view_rect().height();
const int width = right - left;
const int y = get_zeroPos() + height * 0.5;
@ -581,7 +619,8 @@ void DsoSignal::paint_mid(QPainter &p, int left, int right)
if (snapshots.empty())
return;
_scale = height * 1.0f / 256;
if (_view->session().get_capture_state() == SigSession::Running)
_scale = height * 1.0f / 256;
const boost::shared_ptr<pv::data::DsoSnapshot> &snapshot =
snapshots.front();
@ -647,9 +686,19 @@ void DsoSignal::paint_fore(QPainter &p, int left, int right)
p.setBrush(hover ? _colour.dark() : _colour);
p.drawPolygon(points, countof(points));
// paint the trig voltage
int trigp = get_trig_vpos();
float t_vol = (_zeroPos - _trig_vpos) * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS;
QString t_vol_s = (_vDial->get_value() >= 500) ? QString::number(t_vol/1000.0f, 'f', 2)+"V" : QString::number(t_vol, 'f', 2)+"mV";
int vol_width = p.boundingRect(0, 0, INT_MAX, INT_MAX,
Qt::AlignLeft | Qt::AlignTop, t_vol_s).width();
const QRectF t_vol_rect = QRectF(right-vol_width, trigp-10, vol_width, 20);
p.setPen(Qt::white);
p.drawText(t_vol_rect, Qt::AlignRight | Qt::AlignVCenter, t_vol_s);
// paint the _trig_vpos line
p.setPen(QPen(_colour, 1, Qt::DotLine));
p.drawLine(left, get_trig_vpos(), right - label_rect.width()*1.5, get_trig_vpos());
p.drawLine(left, trigp, right - p.boundingRect(t_vol_rect, Qt::AlignLeft, t_vol_s).width(), trigp);
// Paint the text
p.setPen(Qt::white);
@ -687,9 +736,10 @@ void DsoSignal::paint_trace(QPainter &p,
float top = get_view_rect().top();
float bottom = get_view_rect().bottom();
float zeroP = 0;
if (strcmp(_dev_inst->dev_inst()->driver->name, "DSLogic") == 0)
zeroP = (_zeroPos - 0.5) * get_view_rect().height();
float zeroP = _zeroPos * get_view_rect().height() + top;;
if (strcmp(_dev_inst->dev_inst()->driver->name, "DSCope") == 0 &&
_view->session().get_capture_state() == SigSession::Running)
_zero_off = _zeroPos * 255;
float x = (start / samples_per_pixel - pixels_offset) + left;
double pixels_per_sample = 1.0/samples_per_pixel;
uint8_t offset;
@ -700,7 +750,7 @@ void DsoSignal::paint_trace(QPainter &p,
//offset = samples[(sample - start)*num_channels];
offset = samples[sample];
const float y = min(max(top, top + offset * _scale + zeroP), bottom);
const float y = min(max(top, zeroP + (offset - _zero_off) * _scale), bottom);
*point++ = QPointF(x, y);
x += pixels_per_sample;
//*point++ = QPointF(x, top + offset);
@ -738,9 +788,10 @@ void DsoSignal::paint_envelope(QPainter &p,
QRectF *rect = rects;
float top = get_view_rect().top();
float bottom = get_view_rect().bottom();
float zeroP = 0;
if (strcmp(_dev_inst->dev_inst()->driver->name, "DSLogic") == 0)
zeroP = (_zeroPos - 0.5) * get_view_rect().height();
float zeroP = _zeroPos * get_view_rect().height() + top;
if (strcmp(_dev_inst->dev_inst()->driver->name, "DSCope") == 0 &&
_view->session().get_capture_state() == SigSession::Running)
_zero_off = _zeroPos * 255;
for(uint64_t sample = 0; sample < e.length-1; sample++) {
const float x = ((e.scale * sample + e.start) /
samples_per_pixel - pixels_offset) + left;
@ -749,8 +800,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, (top + max(s->max, (s+1)->min) * _scale + zeroP)), bottom);
const float t = min(max(top, (top + min(s->min, (s+1)->max) * _scale + zeroP)), bottom);
const float b = min(max(top, ((max(s->max, (s+1)->min) - _zero_off) * _scale + zeroP)), bottom);
const float t = min(max(top, ((min(s->min, (s+1)->max) - _zero_off) * _scale + zeroP)), bottom);
float h = b - t;
if(h >= 0.0f && h <= 1.0f)
@ -776,6 +827,9 @@ void DsoSignal::paint_type_options(QPainter &p, int right, bool hover, int actio
{
int y = get_y();
const QRectF vDial_rect = get_rect("vDial", y, right);
const QRectF x1_rect = get_rect("x1", y, right);
const QRectF x10_rect = get_rect("x10", y, right);
const QRectF x100_rect = get_rect("x100", y, right);
const QRectF hDial_rect = get_rect("hDial", y, right);
const QRectF acdc_rect = get_rect("acdc", y, right);
const QRectF chEn_rect = get_rect("chEn", y, right);
@ -797,6 +851,31 @@ void DsoSignal::paint_type_options(QPainter &p, int right, bool hover, int actio
p.setPen(Qt::white);
p.drawText(acdc_rect, Qt::AlignCenter | Qt::AlignVCenter, (_acCoupling == SR_GND_COUPLING) ? "GND" :
(_acCoupling == SR_DC_COUPLING) ? "DC" : "AC");
// paint the probe factor selector
GVariant* gvar;
uint64_t factor;
gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_FACTOR);
if (gvar != NULL) {
factor = g_variant_get_uint64(gvar);
g_variant_unref(gvar);
} else {
qDebug() << "ERROR: config_get SR_CONF_FACTOR failed.";
return;
}
p.setPen(Qt::white);
p.setBrush((enabled() && (factor == 100)) ? ((hover && action == X100) ? _colour.darker() : _colour) : ((hover && action == X100) ? _colour.darker() : dsDisable));
p.drawRect(x100_rect);
p.drawText(x100_rect, Qt::AlignLeft | Qt::AlignVCenter, "x100");
p.setBrush((enabled() && (factor == 10)) ? ((hover && action == X10) ? _colour.darker() : _colour) : ((hover && action == X10) ? _colour.darker() : dsDisable));
p.drawRect(x10_rect);
p.drawText(x10_rect, Qt::AlignLeft | Qt::AlignVCenter, "x10");
p.setBrush((enabled() && (factor == 1)) ? ((hover && action == X1) ? _colour.darker() : _colour) : ((hover && action == X1) ? _colour.darker() : dsDisable));
p.drawRect(x1_rect);
p.drawText(x1_rect, Qt::AlignLeft | Qt::AlignVCenter, "x1");
}
void DsoSignal::paint_measure(QPainter &p)
@ -808,26 +887,26 @@ void DsoSignal::paint_measure(QPainter &p)
if (sr_status_get(_dev_inst->dev_inst(), &status, st_begin, st_end) == SR_OK) {
_max = (index == 0) ? status.ch0_max : status.ch1_max;
_min = (index == 0) ? status.ch0_min : status.ch1_min;
const uint32_t period = (index == 0) ? status.ch0_period : status.ch1_period;
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 = ((0xff - _min - (1-_zeroPos)*0xff) * _vDial->get_value() * DS_CONF_DSO_VDIVS) / 0xff;
double value_min = ((0xff - _max - (1-_zeroPos)*0xff) * _vDial->get_value() * DS_CONF_DSO_VDIVS) / 0xff;
_period = (count == 0) ? period * 10 : period * 10.0f / count;
double value_max = (_zero_off - _min) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height();
double value_min = (_zero_off - _max) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height();
_period = (count == 0) ? period * 10.0 : period * 10.0 / count;
const int channel_count = _view->session().get_ch_num(SR_CHANNEL_DSO);
uint64_t sample_rate = _dev_inst->get_sample_rate();
_period = _period * 200 / (channel_count * sample_rate * 1.0 / SR_MHZ(1));
QString max_string = abs(value_max) > 1000 ? QString::number(value_max/1000.0) + "V" : QString::number(value_max) + "mV";
QString min_string = abs(value_min) > 1000 ? QString::number(value_min/1000.0) + "V" : QString::number(value_min) + "mV";
QString period_string = abs(_period) > 1000000000 ? QString::number(_period/1000000000) + "S" :
abs(_period) > 1000000 ? QString::number(_period/1000000) + "mS" :
abs(_period) > 1000 ? QString::number(_period/1000) + "uS" : QString::number(_period) + "nS";
QString freq_string = abs(_period) > 1000000 ? QString::number(1000000000/_period) + "Hz" :
abs(_period) > 1000 ? QString::number(1000000/_period) + "kHz" : QString::number(1000/_period) + "MHz";
_period = _period * 200.0 / (channel_count * sample_rate * 1.0 / SR_MHZ(1));
QString max_string = abs(value_max) > 1000 ? QString::number(value_max/1000.0, 'f', 2) + "V" : QString::number(value_max, 'f', 2) + "mV";
QString min_string = abs(value_min) > 1000 ? QString::number(value_min/1000.0, 'f', 2) + "V" : QString::number(value_min, 'f', 2) + "mV";
QString period_string = abs(_period) > 1000000000 ? QString::number(_period/1000000000, 'f', 2) + "S" :
abs(_period) > 1000000 ? QString::number(_period/1000000, 'f', 2) + "mS" :
abs(_period) > 1000 ? QString::number(_period/1000, 'f', 2) + "uS" : QString::number(_period, 'f', 2) + "nS";
QString freq_string = abs(_period) > 1000000 ? QString::number(1000000000/_period, 'f', 2) + "Hz" :
abs(_period) > 1000 ? QString::number(1000000/_period, 'f', 2) + "kHz" : QString::number(1000/_period, 'f', 2) + "MHz";
p.setPen(_colour);
p.drawText(QRectF(0, 100*index + UpMargin, get_view_rect().width(), 20), Qt::AlignRight | Qt::AlignVCenter, "Max: "+max_string+" ");
p.drawText(QRectF(0, 100*index + UpMargin + 20, get_view_rect().width(), 20), Qt::AlignRight | Qt::AlignVCenter, "Min: "+min_string+" ");
p.drawText(QRectF(0, 100*index + UpMargin + 40, get_view_rect().width(), 20), Qt::AlignRight | Qt::AlignVCenter, "Period: "+period_string+" ");
p.drawText(QRectF(0, 100*index + UpMargin + 60, get_view_rect().width(), 20), Qt::AlignRight | Qt::AlignVCenter, "Frequency: "+freq_string+" ");
p.drawText(QRectF(0, 100*index + UpMargin, get_view_rect().width()*0.9, 20), Qt::AlignRight | Qt::AlignVCenter, "Max: "+max_string+" ");
p.drawText(QRectF(0, 100*index + UpMargin + 20, get_view_rect().width()*0.9, 20), Qt::AlignRight | Qt::AlignVCenter, "Min: "+min_string+" ");
p.drawText(QRectF(0, 100*index + UpMargin + 40, get_view_rect().width()*0.9, 20), Qt::AlignRight | Qt::AlignVCenter, "Period: "+period_string+" ");
p.drawText(QRectF(0, 100*index + UpMargin + 60, get_view_rect().width()*0.9, 20), Qt::AlignRight | Qt::AlignVCenter, "Frequency: "+freq_string+" ");
if (_autoV) {
const uint8_t vscale = abs(_max - _min);
@ -880,5 +959,78 @@ void DsoSignal::auto_set()
}
}
bool DsoSignal::measure(const QPointF &p)
{
_hover_en = false;
if (!enabled())
return false;
const deque< boost::shared_ptr<pv::data::DsoSnapshot> > &snapshots =
_data->get_snapshots();
if (snapshots.empty())
return false;
const boost::shared_ptr<pv::data::DsoSnapshot> &snapshot =
snapshots.front();
if (snapshot->buf_null())
return false;
const double scale = _view->scale();
assert(scale > 0);
const double offset = _view->offset();
const double pixels_offset = offset / scale;
const double samplerate = _dev_inst->get_sample_rate();
const double samples_per_pixel = samplerate * scale;
_hover_index = floor((p.x() + pixels_offset) * samples_per_pixel+0.5);
if (_hover_index >= snapshot->get_sample_count())
return false;
uint64_t pre_index;
uint64_t nxt_index;
if (_hover_index > 0)
pre_index = _hover_index - 1;
else
pre_index = _hover_index;
if (_hover_index < snapshot->get_sample_count() - 1)
nxt_index = _hover_index + 1;
else
nxt_index = _hover_index;
const uint8_t pre_sample = *snapshot->get_samples(pre_index, pre_index, get_index());
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 = (_zero_off - 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 = _zeroPos * 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 - _zero_off)* _scale), bottom);
float x = (_hover_index / samples_per_pixel - pixels_offset);
const float y = min(max(top, zeroP + (cur_sample - _zero_off)* _scale), bottom);
float nxt_x = (nxt_index / samples_per_pixel - pixels_offset);
const float nxt_y = min(max(top, zeroP + (nxt_sample - _zero_off)* _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);
_hover_en = true;
return true;
} else {
return false;
}
}
bool DsoSignal::get_hover(uint64_t &index, QPointF &p, double &value)
{
if (_hover_en) {
index = _hover_index;
p = _hover_point;
value = _hover_value;
return true;
}
return false;
}
} // namespace view
} // namespace pv

View File

@ -45,8 +45,8 @@ private:
static const float EnvelopeThreshold;
static const int HitCursorMargin = 3;
static const quint64 vDialValueCount = 8;
static const quint64 vDialValueStep = 1000;
static const uint64_t vDialValueCount = 8;
static const uint64_t vDialValueStep = 1000;
static const uint64_t vDialUnitCount = 2;
static const uint64_t hDialValueCount = 28;
static const uint64_t hDialValueStep = 1000;
@ -94,6 +94,13 @@ public:
void set_acCoupling(uint8_t coupling);
void set_trig_vpos(int pos);
int get_trig_vpos() const;
void set_factor(uint64_t factor);
/**
*
*/
bool measure(const QPointF &p);
bool get_hover(uint64_t &index, QPointF &p, double &value);
/**
* auto set the vertical and Horizontal scale
@ -171,12 +178,18 @@ private:
double _trig_vpos;
double _zeroPos;
float _zero_off;
uint8_t _max;
uint8_t _min;
double _period;
bool _autoV;
bool _autoH;
bool _hover_en;
uint64_t _hover_index;
QPointF _hover_point;
double _hover_value;
};
} // namespace view

View File

@ -282,6 +282,21 @@ void Header::mousePressEvent(QMouseEvent *event)
else
dsoSig->set_acCoupling((dsoSig->get_acCoupling()+1)%3);
}
} else if (action == Trace::X1 && mTrace) {
boost::shared_ptr<view::DsoSignal> dsoSig;
if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(mTrace)) {
dsoSig->set_factor(1);
}
} else if (action == Trace::X10 && mTrace) {
boost::shared_ptr<view::DsoSignal> dsoSig;
if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(mTrace)) {
dsoSig->set_factor(10);
}
} else if (action == Trace::X100 && mTrace) {
boost::shared_ptr<view::DsoSignal> dsoSig;
if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(mTrace)) {
dsoSig->set_factor(100);
}
}
if (~QApplication::keyboardModifiers() & Qt::ControlModifier) {

View File

@ -300,6 +300,9 @@ int Trace::pt_in_rect(int y, int right, const QPoint &point)
const QRectF edgeTrig = get_rect("edgeTrig", y, right);
const QRectF label = get_rect("label", get_zeroPos(), right);
const QRectF vDial = get_rect("vDial", y, right);
const QRectF x1 = get_rect("x1", y, right);
const QRectF x10 = get_rect("x10", y, right);
const QRectF x100 = get_rect("x100", y, right);
const QRectF hDial = get_rect("hDial", y, right);
const QRectF chEn = get_rect("chEn", y, right);
const QRectF acdc = get_rect("acdc", y, right);
@ -323,6 +326,12 @@ int Trace::pt_in_rect(int y, int right, const QPoint &point)
return LABEL;
else if (vDial.contains(point) && _type == DS_DSO && enabled())
return VDIAL;
else if (x1.contains(point) && _type == DS_DSO && enabled())
return X1;
else if (x10.contains(point) && _type == DS_DSO && enabled())
return X10;
else if (x100.contains(point) && _type == DS_DSO && enabled())
return X100;
else if (hDial.contains(point) && _type == DS_DSO && enabled())
return HDIAL;
else if (chEn.contains(point) && _type == DS_DSO)
@ -400,6 +409,21 @@ QRectF Trace::get_rect(const char *s, int y, int right)
get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin,
y - SquareWidth * SquareNum,
SquareWidth * (SquareNum-1), SquareWidth * (SquareNum-1));
else if (!strcmp(s, "x1"))
return QRectF(
get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin - 45,
y - SquareWidth - SquareWidth * (SquareNum-1) * 0.85,
SquareWidth * 1.75, SquareWidth);
else if (!strcmp(s, "x10"))
return QRectF(
get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin - 45,
y - SquareWidth - SquareWidth * (SquareNum-1) * 0.55,
SquareWidth * 1.75, SquareWidth);
else if (!strcmp(s, "x100"))
return QRectF(
get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin - 45,
y - SquareWidth - SquareWidth * (SquareNum-1) * 0.25,
SquareWidth * 1.75, SquareWidth);
else if (!strcmp(s, "hDial"))
return QRectF(
get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin,

View File

@ -66,6 +66,9 @@ public:
static const int CHEN = 11;
static const int ACDC = 12;
static const int DSOTRIG = 13;
static const int X1 = 14;
static const int X10 = 15;
static const int X100 = 16;
static const QColor dsBlue;
static const QColor dsYellow;

View File

@ -96,12 +96,10 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget
setViewportMargins(headerWidth(), RulerHeight, 0, 0);
setViewport(_viewport);
connect(&_session, SIGNAL(signals_changed()),
this, SLOT(signals_changed()));
connect(&_session, SIGNAL(data_updated()),
this, SLOT(data_updated()));
connect(&_session, SIGNAL(receive_data(quint64)),
this, SLOT(receive_data(quint64)));
connect(&_session, SIGNAL(signals_changed()),
this, SLOT(signals_changed()));
connect(&_session, SIGNAL(data_updated()),
this, SLOT(data_updated()));
connect(&_session, SIGNAL(receive_trigger(quint64)),
this, SLOT(set_trig_pos(quint64)));
@ -550,7 +548,7 @@ bool View::viewportEvent(QEvent *e)
int View::headerWidth()
{
int headerWidth;
int maxNameWidth = 0;
int maxNameWidth = 25;
int maxLeftWidth = 0;
int maxRightWidth = 0;
@ -580,7 +578,11 @@ void View::resizeEvent(QResizeEvent*)
if (_session.get_device()->dev_inst()->mode == DSO)
_scale = _session.get_device()->get_time_base() * std::pow(10.0, -9.0) * DS_CONF_DSO_HDIVS / get_view_width();
_maxscale = _session.get_device()->get_sample_time() / (get_view_width() * MaxViewRate);
if (_session.get_device()->dev_inst()->mode != DSO)
_maxscale = _session.get_device()->get_sample_time() / (get_view_width() * MaxViewRate);
else
_maxscale = 1e9;
_scale = min(_scale, _maxscale);
signals_changed();
@ -722,11 +724,6 @@ void View::set_cursor_middle(int index)
set_scale_offset(_scale, (*i)->index() * 1.0 / _session.get_device()->get_sample_rate() - _scale * get_view_width() / 2);
}
void View::receive_data(quint64 length)
{
_viewport->set_receive_len(length);
}
Viewport * View::get_viewport()
{
return _viewport;

View File

@ -225,8 +225,6 @@ private slots:
void header_updated();
void receive_data(quint64 length);
void set_trig_pos(quint64 trig_pos);
private:

View File

@ -52,11 +52,14 @@ Viewport::Viewport(View &parent) :
_total_receive_len(0),
_zoom_rect_visible(false),
_measure_shown(false),
_measure_type(LOGIC),
_cur_sample(0),
_nxt_sample(1),
_cur_preX(0),
_cur_aftX(1),
_cur_midY(0)
_cur_midY(0),
_hover_index(0),
_hover_hit(false)
{
setMouseTracking(true);
setAutoFillBackground(true);
@ -75,6 +78,9 @@ Viewport::Viewport(View &parent) :
this, SLOT(on_traces_moved()));
connect(&trigger_timer, SIGNAL(timeout()),
this, SLOT(on_trigger_timer()));
connect(&_view.session(), &SigSession::receive_data,
this, &Viewport::set_receive_len);
}
int Viewport::get_total_height() const
@ -214,7 +220,7 @@ void Viewport::paintProgress(QPainter &p)
{
using pv::view::Signal;
const quint64 _total_sample_len = _view.session().get_device()->get_sample_limit();
const uint64_t _total_sample_len = _view.session().get_device()->get_sample_limit();
double progress = -(_total_receive_len * 1.0 / _total_sample_len * 360 * 16);
int captured_progress = 0;
@ -361,9 +367,6 @@ void Viewport::mousePressEvent(QMouseEvent *event)
}
}
// if (!_view.get_ruler()->get_grabbed_cursor()) {
// _zoom_rect_visible = true;
// }
const vector< boost::shared_ptr<Signal> > sigs(_view.session().get_signals());
BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
@ -384,6 +387,7 @@ void Viewport::mouseMoveEvent(QMouseEvent *event)
{
assert(event);
_mouse_point = event->pos();
_hover_hit = false;
if (event->buttons() & Qt::RightButton) {
_zoom_rect = QRectF(_mouse_down_point, event->pos());
_zoom_rect_visible = true;
@ -437,6 +441,13 @@ void Viewport::mouseReleaseEvent(QMouseEvent *event)
if(_drag_sig)
_drag_sig.reset();
if (_hover_hit){
_view.add_cursor(view::Ruler::CursorColor[_view.get_cursorList().size() % 8], _hover_index);
_view.show_cursors(true);
_hover_hit = false;
}
update();
}
@ -505,14 +516,17 @@ void Viewport::measure()
{
if (_view.session().get_capture_state() == SigSession::Running)
return;
_measure_shown = false;
const uint64_t sample_rate = _view.session().get_device()->get_sample_rate();
const vector< boost::shared_ptr<Signal> > sigs(_view.session().get_signals());
BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
assert(s);
boost::shared_ptr<view::LogicSignal> logicSig;
boost::shared_ptr<view::DsoSignal> dsoSig;
if (logicSig = dynamic_pointer_cast<view::LogicSignal>(s)) {
if (logicSig->measure(_view.hover_point(), _cur_sample, _nxt_sample, _thd_sample)) {
_measure_shown = true;
_measure_type = LOGIC;
_mm_width = _view.get_ruler()->format_real_time(_nxt_sample - _cur_sample, sample_rate);
_mm_period = _thd_sample != 0 ? _view.get_ruler()->format_real_time(_thd_sample - _cur_sample, sample_rate) : "#####";
@ -528,7 +542,7 @@ void Viewport::measure()
_mm_duty = _thd_sample != 0 ? QString::number((_nxt_sample - _cur_sample) * 100.0 / (_thd_sample - _cur_sample), 'f', 2)+"%" :
"#####";
mouse_measure();
return;
break;
} else {
_mm_width = "#####";
_mm_period = "#####";
@ -536,66 +550,127 @@ void Viewport::measure()
_mm_duty = "#####";
}
mouse_measure();
} else if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(s)) {
if (_measure_en && dsoSig->measure(_view.hover_point())) {
_measure_shown = true;
_measure_type = DSO;
}
}
}
_measure_shown = false;
return;
}
void Viewport::paintMeasure(QPainter &p)
{
p.setPen(QColor(17, 133, 209, 255));
p.drawLine(QLineF(_cur_preX, _cur_midY, _cur_aftX, _cur_midY));
p.drawLine(QLineF(_cur_preX, _cur_midY, _cur_preX + 2, _cur_midY - 2));
p.drawLine(QLineF(_cur_preX, _cur_midY, _cur_preX + 2, _cur_midY + 2));
p.drawLine(QLineF(_cur_aftX - 2, _cur_midY - 2, _cur_aftX, _cur_midY));
p.drawLine(QLineF(_cur_aftX - 2, _cur_midY + 2, _cur_aftX, _cur_midY));
if (_thd_sample != 0) {
p.drawLine(QLineF(_cur_aftX, _cur_midY, _cur_thdX, _cur_midY));
p.drawLine(QLineF(_cur_aftX, _cur_midY, _cur_aftX + 2, _cur_midY - 2));
p.drawLine(QLineF(_cur_aftX, _cur_midY, _cur_aftX + 2, _cur_midY + 2));
p.drawLine(QLineF(_cur_thdX - 2, _cur_midY - 2, _cur_thdX, _cur_midY));
p.drawLine(QLineF(_cur_thdX - 2, _cur_midY + 2, _cur_thdX, _cur_midY));
}
_hover_hit = false;
if (_measure_type == LOGIC) {
p.setPen(QColor(17, 133, 209, 255));
p.drawLine(QLineF(_cur_preX, _cur_midY, _cur_aftX, _cur_midY));
p.drawLine(QLineF(_cur_preX, _cur_midY, _cur_preX + 2, _cur_midY - 2));
p.drawLine(QLineF(_cur_preX, _cur_midY, _cur_preX + 2, _cur_midY + 2));
p.drawLine(QLineF(_cur_aftX - 2, _cur_midY - 2, _cur_aftX, _cur_midY));
p.drawLine(QLineF(_cur_aftX - 2, _cur_midY + 2, _cur_aftX, _cur_midY));
if (_thd_sample != 0) {
p.drawLine(QLineF(_cur_aftX, _cur_midY, _cur_thdX, _cur_midY));
p.drawLine(QLineF(_cur_aftX, _cur_midY, _cur_aftX + 2, _cur_midY - 2));
p.drawLine(QLineF(_cur_aftX, _cur_midY, _cur_aftX + 2, _cur_midY + 2));
p.drawLine(QLineF(_cur_thdX - 2, _cur_midY - 2, _cur_thdX, _cur_midY));
p.drawLine(QLineF(_cur_thdX - 2, _cur_midY + 2, _cur_thdX, _cur_midY));
}
if (_measure_en) {
int typical_width = p.boundingRect(0, 0, INT_MAX, INT_MAX,
Qt::AlignLeft | Qt::AlignTop, _mm_width).width();
typical_width = max(typical_width, p.boundingRect(0, 0, INT_MAX, INT_MAX,
Qt::AlignLeft | Qt::AlignTop, _mm_period).width());
typical_width = max(typical_width, p.boundingRect(0, 0, INT_MAX, INT_MAX,
Qt::AlignLeft | Qt::AlignTop, _mm_freq).width());
typical_width = max(typical_width, p.boundingRect(0, 0, INT_MAX, INT_MAX,
Qt::AlignLeft | Qt::AlignTop, _mm_duty).width());
typical_width = typical_width + 100;
if (_measure_en) {
int typical_width = p.boundingRect(0, 0, INT_MAX, INT_MAX,
Qt::AlignLeft | Qt::AlignTop, _mm_width).width();
typical_width = max(typical_width, p.boundingRect(0, 0, INT_MAX, INT_MAX,
Qt::AlignLeft | Qt::AlignTop, _mm_period).width());
typical_width = max(typical_width, p.boundingRect(0, 0, INT_MAX, INT_MAX,
Qt::AlignLeft | Qt::AlignTop, _mm_freq).width());
typical_width = max(typical_width, p.boundingRect(0, 0, INT_MAX, INT_MAX,
Qt::AlignLeft | Qt::AlignTop, _mm_duty).width());
typical_width = typical_width + 100;
const double width = _view.get_view_width();
const double height = _view.viewport()->height();
const double left = _view.hover_point().x();
const double top = _view.hover_point().y();
const double right = left + typical_width;
const double bottom = top + 80;
QPointF org_pos = QPointF(right > width ? left - typical_width : left, bottom > height ? top - 80 : top);
QRectF measure_rect = QRectF(org_pos.x(), org_pos.y(), (double)typical_width, 80.0);
QRectF measure1_rect = QRectF(org_pos.x(), org_pos.y(), (double)typical_width, 20.0);
QRectF measure2_rect = QRectF(org_pos.x(), org_pos.y()+20, (double)typical_width, 20.0);
QRectF measure3_rect = QRectF(org_pos.x(), org_pos.y()+40, (double)typical_width, 20.0);
QRectF measure4_rect = QRectF(org_pos.x(), org_pos.y()+60, (double)typical_width, 20.0);
const double width = _view.get_view_width();
const double height = _view.viewport()->height();
const double left = _view.hover_point().x();
const double top = _view.hover_point().y();
const double right = left + typical_width;
const double bottom = top + 80;
QPointF org_pos = QPointF(right > width ? left - typical_width : left, bottom > height ? top - 80 : top);
QRectF measure_rect = QRectF(org_pos.x(), org_pos.y(), (double)typical_width, 80.0);
QRectF measure1_rect = QRectF(org_pos.x(), org_pos.y(), (double)typical_width, 20.0);
QRectF measure2_rect = QRectF(org_pos.x(), org_pos.y()+20, (double)typical_width, 20.0);
QRectF measure3_rect = QRectF(org_pos.x(), org_pos.y()+40, (double)typical_width, 20.0);
QRectF measure4_rect = QRectF(org_pos.x(), org_pos.y()+60, (double)typical_width, 20.0);
p.setPen(Qt::NoPen);
p.setBrush(QColor(17, 133, 209, 150));
p.drawRect(measure_rect);
p.setPen(Qt::NoPen);
p.setBrush(QColor(17, 133, 209, 150));
p.drawRect(measure_rect);
p.setPen(Qt::black);
p.drawText(measure1_rect, Qt::AlignRight | Qt::AlignVCenter,
"Width: " + _mm_width);
p.drawText(measure2_rect, Qt::AlignRight | Qt::AlignVCenter,
"Period: " + _mm_period);
p.drawText(measure3_rect, Qt::AlignRight | Qt::AlignVCenter,
"Frequency: " + _mm_freq);
p.drawText(measure4_rect, Qt::AlignRight | Qt::AlignVCenter,
"Duty Cycle: " + _mm_duty);
p.setPen(Qt::black);
p.drawText(measure1_rect, Qt::AlignRight | Qt::AlignVCenter,
"Width: " + _mm_width);
p.drawText(measure2_rect, Qt::AlignRight | Qt::AlignVCenter,
"Period: " + _mm_period);
p.drawText(measure3_rect, Qt::AlignRight | Qt::AlignVCenter,
"Frequency: " + _mm_freq);
p.drawText(measure4_rect, Qt::AlignRight | Qt::AlignVCenter,
"Duty Cycle: " + _mm_duty);
}
} else if (_measure_type == DSO) {
const vector< boost::shared_ptr<Signal> > sigs(_view.session().get_signals());
BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
boost::shared_ptr<view::DsoSignal> dsoSig;
if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(s)) {
uint64_t index;
double value;
QPointF hpoint;
const int arrow_size = 5;
const int mark_radius = 10;
const int mark_width = 20;
const int mark_cursor_height = 30;
if (dsoSig->get_hover(index, hpoint, value)) {
p.setPen(dsoSig->get_colour());
const QRectF hpoint_rect = QRectF(hpoint.x()-mark_radius/2, hpoint.y()-mark_radius/2, mark_radius, mark_radius);
if (hpoint_rect.contains(_view.hover_point())) {
p.setBrush(dsoSig->get_colour());
const int cursor_up = hpoint.y()-mark_cursor_height;
const int cursor_dn = hpoint.y()+mark_cursor_height;
const int cursor_lf = hpoint.x()-arrow_size;
const int cursor_md = hpoint.x();
const int cursor_rt = hpoint.x()+arrow_size;
const QPointF up_arrow[3] = {
QPointF(cursor_lf, cursor_up+arrow_size),
QPointF(cursor_md, cursor_up),
QPointF(cursor_rt, cursor_up+arrow_size),
};
const QPointF dn_arrow[3] = {
QPointF(cursor_lf, cursor_dn-arrow_size),
QPointF(cursor_md, cursor_dn),
QPointF(cursor_rt, cursor_dn-arrow_size),
};
p.drawPolyline(up_arrow, 3);
p.drawPolyline(dn_arrow, 3);
p.drawLine(cursor_md, cursor_up, cursor_md, cursor_dn);
_hover_hit = true;
_hover_index = index;
} else {
p.setBrush(Qt::NoBrush);
}
p.drawEllipse(hpoint, mark_radius, mark_radius);
QString value_c = abs(value) > 1000 ? QString::number(value/1000.0, 'f', 2) + "V" : QString::number(value, 'f', 2) + "mV";
int value_width = p.boundingRect(0, 0, INT_MAX, INT_MAX,
Qt::AlignLeft | Qt::AlignTop, value_c).width();
const bool right = dsoSig->get_index()%2 ? hpoint.x() < value_width : hpoint.x() < _view.get_view_width() - value_width;
const bool up = hpoint.y() > 50;
const QPointF hpoint_sec = QPointF(hpoint.x() - (right ? -mark_width : mark_width), hpoint.y() - (up ? mark_width : -mark_width));
p.drawLine(hpoint, hpoint_sec);
p.drawLine(hpoint_sec, QPointF(hpoint_sec.x() + (right ? value_width : -value_width), hpoint_sec.y()));
p.drawText(QRectF(right ? hpoint_sec.x() : hpoint_sec.x() - value_width, hpoint_sec.y() - mark_width, value_width, mark_width),
Qt::AlignLeft | Qt::AlignBottom,
value_c);
}
}
}
}
}

View File

@ -56,8 +56,6 @@ public:
QPoint get_mouse_point() const;
void set_receive_len(quint64 length);
QString get_measure(QString option);
void set_measure_en(int enable);
@ -85,6 +83,7 @@ private:
private slots:
void on_traces_moved();
void on_trigger_timer();
void set_receive_len(quint64 length);
signals:
void mouse_measure();
@ -92,7 +91,7 @@ signals:
private:
View &_view;
quint64 _total_receive_len;
uint64_t _total_receive_len;
QPoint _mouse_point;
QPoint _mouse_down_point;
double _mouse_down_offset;
@ -107,6 +106,7 @@ private:
bool _measure_en;
bool _measure_shown;
int _measure_type;
uint64_t _cur_sample;
uint64_t _nxt_sample;
uint64_t _thd_sample;
@ -124,6 +124,9 @@ private:
int timer_cnt;
boost::shared_ptr<Signal> _drag_sig;
uint64_t _hover_index;
bool _hover_hit;
};
} // namespace view

Binary file not shown.

View File

@ -249,7 +249,7 @@ static int fpga_setting(const struct sr_dev_inst *sdi)
((sdi->mode == ANALOG) << 7) +
((devc->filter == SR_FILTER_1T) << 8) +
(devc->instant << 9) + (devc->zero << 10);
setting.divider = devc->zero ? 0x1 : (uint32_t)ceil(SR_MHZ(100) * 1.0 / devc->cur_samplerate);
setting.divider = devc->zero ? 0x1 : (uint32_t)ceil(DSCOPE_MAX_SAMPLERATE * 1.0 / devc->cur_samplerate / channel_en_cnt);
setting.count = (uint32_t)(devc->limit_samples / (channel_cnt / channel_en_cnt));
setting.trig_pos = (uint32_t)(trigger->trigger_pos / 100.0 * devc->limit_samples);
setting.trig_glb = trigger->trigger_stages;
@ -847,7 +847,7 @@ static uint64_t dso_cmd_gen(struct sr_dev_inst *sdi, struct sr_channel* ch, int
channel_cnt += probe->enabled;
}
cmd += 0x18;
uint32_t divider = devc->zero ? 0x1 : (uint32_t)ceil(SR_MHZ(100) * 1.0 / devc->cur_samplerate);
uint32_t divider = devc->zero ? 0x1 : (uint32_t)ceil(DSCOPE_MAX_SAMPLERATE * 1.0 / devc->cur_samplerate / channel_cnt);
cmd += divider << 8;
break;
case SR_CONF_HORIZ_TRIGGERPOS:
@ -1174,6 +1174,11 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
return SR_ERR;
*data = g_variant_new_uint64(ch->vdiv);
break;
case SR_CONF_FACTOR:
if (!ch)
return SR_ERR;
*data = g_variant_new_uint64(ch->vfactor);
break;
case SR_CONF_VPOS:
if (!ch)
return SR_ERR;
@ -1422,6 +1427,8 @@ 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) {
ch->vfactor = g_variant_get_uint64(data);
} else if (id == SR_CONF_VPOS) {
ch->vpos = g_variant_get_double(data);
if (sdi->mode == DSO) {
@ -1854,11 +1861,12 @@ static void receive_transfer(struct libusb_transfer *transfer)
mstatus.ch0_max = *((const uint8_t*)cur_buf + mstatus_offset*2 + 1*2);
mstatus.ch0_min = *((const uint8_t*)cur_buf + mstatus_offset*2 + 3);
mstatus.ch0_period = *((const uint32_t*)cur_buf + mstatus_offset/2 + 2/2);
mstatus.ch0_pcnt = *((const uint32_t*)cur_buf + mstatus_offset/2 + 4/2);
mstatus.ch1_max = *((const uint8_t*)cur_buf + mstatus_offset*2 + 7*2);
mstatus.ch1_min = *((const uint8_t*)cur_buf + mstatus_offset*2 + 15);
mstatus.ch1_period = *((const uint32_t*)cur_buf + mstatus_offset/2 + 8/2);
mstatus.ch1_pcnt = *((const uint32_t*)cur_buf + mstatus_offset/2 + 10/2);
mstatus.ch0_period += ((uint64_t)*((const uint32_t*)cur_buf + mstatus_offset/2 + 4/2)) << 32;
mstatus.ch0_pcnt = *((const uint32_t*)cur_buf + mstatus_offset/2 + 6/2);
mstatus.ch1_max = *((const uint8_t*)cur_buf + mstatus_offset*2 + 9*2);
mstatus.ch1_min = *((const uint8_t*)cur_buf + mstatus_offset*2 + 19);
mstatus.ch1_period = *((const uint32_t*)cur_buf + mstatus_offset/2 + 10/2);
mstatus.ch1_period += ((uint64_t)*((const uint32_t*)cur_buf + mstatus_offset/2 + 12/2)) << 32;
mstatus.vlen = *((const uint32_t*)cur_buf + mstatus_offset/2 + 16/2) & 0x7fffffff;
mstatus.stream_mode = *((const uint32_t*)cur_buf + mstatus_offset/2 + 16/2) & 0x80000000;
mstatus.sample_divider = *((const uint32_t*)cur_buf + mstatus_offset/2 + 18/2);
@ -1880,7 +1888,7 @@ static void receive_transfer(struct libusb_transfer *transfer)
mstatus.vlen = instant_buffer_size;
}
const uint32_t divider = devc->zero ? 0x1 : (uint32_t)ceil(SR_MHZ(100) * 1.0 / devc->cur_samplerate);
const uint32_t divider = devc->zero ? 0x1 : (uint32_t)ceil(DSCOPE_MAX_SAMPLERATE * 1.0 / devc->cur_samplerate / channel_en_cnt);
if ((mstatus.sample_divider == divider &&
mstatus.vlen != 0 &&
mstatus.vlen <= (transfer->actual_length - 512) / sample_width) ||

View File

@ -287,7 +287,10 @@ static int fpga_setting(const struct sr_dev_inst *sdi)
((sdi->mode == ANALOG) << 7) +
((devc->filter == SR_FILTER_1T) << 8) +
(devc->instant << 9) + (devc->zero << 10);
setting.divider = devc->zero ? 0x1 : (uint32_t)ceil(SR_MHZ(100) * 1.0 / devc->cur_samplerate);
if (sdi->mode == DSO)
setting.divider = devc->zero ? 0x1 : (uint32_t)ceil(DSLOGIC_MAX_DSO_SAMPLERATE * 1.0 / devc->cur_samplerate / channel_en_cnt);
else
setting.divider = devc->zero ? 0x1 : (uint32_t)ceil(DSLOGIC_MAX_LOGIC_SAMPLERATE * 1.0 / devc->cur_samplerate);
setting.count = (sdi->mode == DSO) ? (uint32_t)(devc->limit_samples / (channel_cnt / channel_en_cnt)) : (uint32_t)(devc->limit_samples);
setting.trig_pos = (uint32_t)(trigger->trigger_pos / 100.0 * devc->limit_samples);
setting.trig_glb = trigger->trigger_stages;
@ -882,7 +885,7 @@ static uint64_t dso_cmd_gen(struct sr_dev_inst *sdi, struct sr_channel* ch, int
channel_cnt += probe->enabled;
}
cmd += 0x18;
uint32_t divider = devc->zero ? 0x1 : (uint32_t)ceil(SR_MHZ(100) * 1.0 / devc->cur_samplerate);
uint32_t divider = devc->zero ? 0x1 : (uint32_t)ceil(DSLOGIC_MAX_DSO_SAMPLERATE * 1.0 / devc->cur_samplerate / channel_cnt);
cmd += divider << 8;
break;
case SR_CONF_HORIZ_TRIGGERPOS:
@ -1157,6 +1160,11 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
return SR_ERR;
*data = g_variant_new_uint64(ch->vdiv);
break;
case SR_CONF_FACTOR:
if (!ch)
return SR_ERR;
*data = g_variant_new_uint64(ch->vfactor);
break;
case SR_CONF_TIMEBASE:
if (!sdi)
return SR_ERR;
@ -1519,6 +1527,8 @@ 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) {
ch->vfactor = g_variant_get_uint64(data);
} else if (id == SR_CONF_TIMEBASE) {
devc->timebase = g_variant_get_uint64(data);
} else if (id == SR_CONF_COUPLING) {
@ -1936,11 +1946,13 @@ static void receive_transfer(struct libusb_transfer *transfer)
mstatus.ch0_max = *((const uint8_t*)cur_buf + mstatus_offset*2 + 1*2);
mstatus.ch0_min = *((const uint8_t*)cur_buf + mstatus_offset*2 + 3);
mstatus.ch0_period = *((const uint32_t*)cur_buf + mstatus_offset/2 + 2/2);
mstatus.ch0_pcnt = *((const uint32_t*)cur_buf + mstatus_offset/2 + 4/2);
mstatus.ch1_max = *((const uint8_t*)cur_buf + mstatus_offset*2 + 7*2);
mstatus.ch1_min = *((const uint8_t*)cur_buf + mstatus_offset*2 + 15);
mstatus.ch1_period = *((const uint32_t*)cur_buf + mstatus_offset/2 + 8/2);
mstatus.ch1_pcnt = *((const uint32_t*)cur_buf + mstatus_offset/2 + 10/2);
mstatus.ch0_period += *((const uint32_t*)cur_buf + mstatus_offset/2 + 4/2) << 32;
mstatus.ch0_pcnt = *((const uint32_t*)cur_buf + mstatus_offset/2 + 6/2);
mstatus.ch1_max = *((const uint8_t*)cur_buf + mstatus_offset*2 + 9*2);
mstatus.ch1_min = *((const uint8_t*)cur_buf + mstatus_offset*2 + 19);
mstatus.ch1_period = *((const uint32_t*)cur_buf + mstatus_offset/2 + 10/2);
mstatus.ch1_period += *((const uint32_t*)cur_buf + mstatus_offset/2 + 12/2) << 32;
mstatus.ch1_pcnt = *((const uint32_t*)cur_buf + mstatus_offset/2 + 14/2);
mstatus.vlen = *((const uint32_t*)cur_buf + mstatus_offset/2 + 16/2) & 0x7fffffff;
mstatus.stream_mode = *((const uint32_t*)cur_buf + mstatus_offset/2 + 16/2) & 0x80000000;
mstatus.sample_divider = *((const uint32_t*)cur_buf + mstatus_offset/2 + 18/2);
@ -1955,7 +1967,7 @@ static void receive_transfer(struct libusb_transfer *transfer)
} else {
mstatus.vlen = instant_buffer_size;
}
const uint32_t divider = devc->zero ? 0x1 : (uint32_t)ceil(SR_MHZ(100) * 1.0 / devc->cur_samplerate);
const uint32_t divider = devc->zero ? 0x1 : (uint32_t)ceil(DSLOGIC_MAX_DSO_SAMPLERATE * 1.0 / devc->cur_samplerate / channel_en_cnt);
if ((mstatus.sample_divider == divider &&
mstatus.vlen != 0 &&
mstatus.vlen <= (transfer->actual_length - 512) / sample_width) ||

View File

@ -344,6 +344,9 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi,
case SR_CONF_VDIV:
*data = g_variant_new_uint64(ch->vdiv);
break;
case SR_CONF_FACTOR:
*data = g_variant_new_uint64(ch->vfactor);
break;
case SR_CONF_TIMEBASE:
*data = g_variant_new_uint64(devc->timebase);
break;
@ -424,6 +427,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi,
ret = SR_ERR;
else {
probe->vdiv = 1000;
probe->vfactor = 1;
probe->coupling = SR_DC_COUPLING;
probe->trig_value = 0x80;
sdi->channels = g_slist_append(sdi->channels, probe);
@ -472,6 +476,11 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi,
sr_dbg("%s: setting VDIV of channel %d to %" PRIu64, __func__,
ch->index, ch->vdiv);
ret = SR_OK;
} else if (id == SR_CONF_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_TIMEBASE) {
devc->timebase = g_variant_get_uint64(data);
sr_dbg("%s: setting TIMEBASE to %" PRIu64, __func__,

View File

@ -83,6 +83,8 @@ static struct sr_config_info sr_config_info_data[] = {
"Filter Targets", NULL},
{SR_CONF_VDIV, SR_T_RATIONAL_VOLT, "vdiv",
"Volts/div", NULL},
{SR_CONF_VDIV, SR_T_RATIONAL_VOLT, "factor",
"Probe Factor", NULL},
{SR_CONF_COUPLING, SR_T_CHAR, "coupling",
"Coupling", NULL},
{SR_CONF_DATALOG, SR_T_BOOL, "datalog",

View File

@ -32,7 +32,7 @@
#define WINVER 0x0501
#define _WIN32_WINNT WINVER
#include <Winsock2.h>
#include <ddk/usbiodef.h>
#include <usbiodef.h>
#endif
#ifdef __cplusplus
@ -389,7 +389,7 @@ struct sr_input_format {
/**
* Load a file, parsing the input according to the file's format.
*
*
* This function will send datafeed packets to the session bus, so
* the calling frontend must have registered its session callbacks
* beforehand.
@ -404,7 +404,7 @@ struct sr_input_format {
* the responsibility of the caller to free it later.
* @param filename The name (and path) of the file to use.
*
* @return SR_OK upon success, a negative error code upon failure.
* @return SR_OK upon succcess, a negative error code upon failure.
*/
int (*loadfile) (struct sr_input *in, const char *filename);
};
@ -610,11 +610,11 @@ struct sr_status {
uint8_t ch0_max;
uint8_t ch0_min;
uint32_t ch0_period;
uint64_t ch0_period;
uint32_t ch0_pcnt;
uint8_t ch1_max;
uint8_t ch1_min;
uint32_t ch1_period;
uint64_t ch1_period;
uint32_t ch1_pcnt;
uint32_t vlen;
@ -767,6 +767,9 @@ enum {
/** Channel enable for dso channel. */
SR_CONF_EN_CH,
/** probe factor for dso channel. */
SR_CONF_FACTOR,
/** Trigger types. */
SR_CONF_TRIGGER_TYPE,