2
0
forked from Ivasoft/DSView

Add DSLogic hardware support

This commit is contained in:
DreamSourceLab
2014-04-14 17:46:11 +08:00
parent a76c4b4a5f
commit 264a094168
300 changed files with 305141 additions and 284 deletions

View File

@@ -0,0 +1,48 @@
/*
* This file is part of the DSLogic-gui project.
* DSLogic-gui is based on PulseView.
*
* Copyright (C) 2013 DreamSourceLab <dreamsourcelab@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 "dso.h"
#include "dsosnapshot.h"
using namespace boost;
using namespace std;
namespace pv {
namespace data {
Dso::Dso(unsigned int num_probes, uint64_t samplerate) :
SignalData(num_probes, samplerate)
{
}
void Dso::push_snapshot(shared_ptr<DsoSnapshot> &snapshot)
{
_snapshots.push_front(snapshot);
}
deque< shared_ptr<DsoSnapshot> >& Dso::get_snapshots()
{
return _snapshots;
}
} // namespace data
} // namespace pv

54
DSLogic-gui/pv/data/dso.h Normal file
View File

@@ -0,0 +1,54 @@
/*
* This file is part of the DSLogic-gui project.
* DSLogic-gui is based on PulseView.
*
* Copyright (C) 2013 DreamSourceLab <dreamsourcelab@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 DSLOGIC_PV_DATA_DSO_H
#define DSLOGIC_PV_DATA_DSO_H
#include "signaldata.h"
#include <boost/shared_ptr.hpp>
#include <deque>
namespace pv {
namespace data {
class DsoSnapshot;
class Dso : public SignalData
{
public:
Dso(unsigned int num_probes, uint64_t samplerate);
void push_snapshot(
boost::shared_ptr<DsoSnapshot> &snapshot);
std::deque< boost::shared_ptr<DsoSnapshot> >&
get_snapshots();
private:
std::deque< boost::shared_ptr<DsoSnapshot> > _snapshots;
};
} // namespace data
} // namespace pv
#endif // DSLOGIC_PV_DATA_DSO_H

View File

@@ -0,0 +1,232 @@
/*
* This file is part of the DSLogic-gui project.
* DSLogic-gui is based on PulseView.
*
* Copyright (C) 2013 DreamSourceLab <dreamsourcelab@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 <extdef.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <algorithm>
#include <boost/foreach.hpp>
#include "dsosnapshot.h"
using namespace boost;
using namespace std;
namespace pv {
namespace data {
const int DsoSnapshot::EnvelopeScalePower = 4;
const int DsoSnapshot::EnvelopeScaleFactor = 1 << EnvelopeScalePower;
const float DsoSnapshot::LogEnvelopeScaleFactor =
logf(EnvelopeScaleFactor);
const uint64_t DsoSnapshot::EnvelopeDataUnit = 64*1024; // bytes
DsoSnapshot::DsoSnapshot(const sr_datafeed_dso &dso, uint64_t _total_sample_len, unsigned int channel_num) :
Snapshot(sizeof(uint16_t), _total_sample_len, channel_num)
{
lock_guard<recursive_mutex> lock(_mutex);
memset(_envelope_levels, 0, sizeof(_envelope_levels));
init(_total_sample_len * channel_num);
append_payload(dso);
}
DsoSnapshot::~DsoSnapshot()
{
lock_guard<recursive_mutex> lock(_mutex);
BOOST_FOREACH(Envelope &e, _envelope_levels[0])
free(e.samples);
}
void DsoSnapshot::append_payload(const sr_datafeed_dso &dso)
{
lock_guard<recursive_mutex> lock(_mutex);
append_data(dso.data, dso.num_samples);
// Generate the first mip-map from the data
append_payload_to_envelope_levels();
}
const uint16_t* DsoSnapshot::get_samples(
int64_t start_sample, int64_t end_sample) const
{
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);
lock_guard<recursive_mutex> lock(_mutex);
// 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;
}
void DsoSnapshot::get_envelope_section(EnvelopeSection &s,
uint64_t start, uint64_t end, float min_length, int probe_index) const
{
assert(end <= get_sample_count());
assert(start <= end);
assert(min_length > 0);
lock_guard<recursive_mutex> lock(_mutex);
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.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;
}
void DsoSnapshot::reallocate_envelope(Envelope &e)
{
const uint64_t new_data_length = ((e.length + EnvelopeDataUnit - 1) /
EnvelopeDataUnit) * EnvelopeDataUnit;
if (new_data_length > e.data_length)
{
e.data_length = new_data_length;
e.samples = (EnvelopeSample*)realloc(e.samples,
new_data_length * sizeof(EnvelopeSample));
}
}
void DsoSnapshot::append_payload_to_envelope_levels()
{
unsigned int i;
for (i = 0; i < _channel_num; i++) {
Envelope &e0 = _envelope_levels[i][0];
uint64_t prev_length;
EnvelopeSample *dest_ptr;
// Expand the data buffer to fit the new samples
prev_length = e0.length;
e0.length = get_sample_count() / EnvelopeScaleFactor;
// Break off if there are no new samples to compute
// if (e0.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;
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;
}
*dest_ptr++ = sub_sample;
}
// Compute higher level mipmaps
for (unsigned int level = 1; level < ScaleStepCount; level++)
{
Envelope &e = _envelope_levels[i][level];
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;
// Break off if there are no more samples to computed
// if (e.length == prev_length)
// break;
if (e.length == prev_length)
prev_length = 0;
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 =
src_ptr + EnvelopeScaleFactor;
EnvelopeSample sub_sample = *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++;
}
*dest_ptr = sub_sample;
}
}
}
}
} // namespace data
} // namespace pv

View File

@@ -0,0 +1,97 @@
/*
* This file is part of the DSLogic-gui project.
* DSLogic-gui is based on PulseView.
*
* Copyright (C) 2013 DreamSourceLab <dreamsourcelab@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 DSLOGIC_PV_DATA_DSOSNAPSHOT_H
#define DSLOGIC_PV_DATA_DSOSNAPSHOT_H
#include "snapshot.h"
#include <utility>
#include <vector>
namespace DsoSnapshotTest {
class Basic;
}
namespace pv {
namespace data {
class DsoSnapshot : public Snapshot
{
public:
struct EnvelopeSample
{
uint16_t min;
uint16_t max;
};
struct EnvelopeSection
{
uint64_t start;
unsigned int scale;
uint64_t length;
EnvelopeSample *samples;
};
private:
struct Envelope
{
uint64_t length;
uint64_t data_length;
EnvelopeSample *samples;
};
private:
static const unsigned int ScaleStepCount = 10;
static const int EnvelopeScalePower;
static const int EnvelopeScaleFactor;
static const float LogEnvelopeScaleFactor;
static const uint64_t EnvelopeDataUnit;
public:
DsoSnapshot(const sr_datafeed_dso &dso, uint64_t _total_sample_len, unsigned int channel_num);
virtual ~DsoSnapshot();
void append_payload(const sr_datafeed_dso &dso);
const uint16_t* get_samples(int64_t start_sample,
int64_t end_sample) const;
void get_envelope_section(EnvelopeSection &s,
uint64_t start, uint64_t end, float min_length, int probe_index) const;
private:
void reallocate_envelope(Envelope &l);
void append_payload_to_envelope_levels();
private:
struct Envelope _envelope_levels[2*DS_MAX_DSO_PROBES_NUM][ScaleStepCount];
friend class DsoSnapshotTest::Basic;
};
} // namespace data
} // namespace pv
#endif // DSLOGIC_PV_DATA_DSOSNAPSHOT_H

View File

@@ -29,12 +29,15 @@
#include <stdexcept>
#include <string>
#include <QtGui/QApplication>
#include <QObject>
#include <QDebug>
#include <QDir>
#include <libsigrok4DSLogic/libsigrok.h>
using namespace std;
char config_path[256];
namespace pv {
@@ -98,6 +101,15 @@ list<sr_dev_inst*> DeviceManager::driver_scan(
// Release this driver and all it's attached devices
release_driver(driver);
// Check If DSLogic driver
if (strcmp(driver->name, "DSLogic") == 0) {
QDir dir(QApplication::applicationDirPath());
if (!dir.cd("res"))
return driver_devices;
std::string str = dir.absolutePath().toStdString() + "/";
strcpy(config_path, str.c_str());
}
// Do the scan
GSList *const devices = sr_driver_scan(driver, drvopts);
for (GSList *l = devices; l; l = l->next)

View File

@@ -51,6 +51,7 @@ DeviceOptions::DeviceOptions(QWidget *parent, struct sr_dev_inst *sdi) :
setLayout(&_layout);
_mode_comboBox.addItem(mode_strings[LOGIC]);
_mode_comboBox.addItem(mode_strings[DSO]);
_mode_comboBox.addItem(mode_strings[ANALOG]);
_mode_comboBox.setCurrentIndex(_sdi->mode);
_props_box.setLayout(&_props_box_layout);

View File

@@ -32,6 +32,8 @@
#include <QPainter>
#include <QRegExpValidator>
#include "libsigrok4DSLogic/libsigrok.h"
namespace pv {
namespace dock {

View File

@@ -31,6 +31,8 @@
#include <QRegExpValidator>
#include <QMessageBox>
#include "libsigrok4DSLogic/libsigrok.h"
namespace pv {
namespace dock {

View File

@@ -242,12 +242,14 @@ void MainWindow::setup_ui()
// Populate the device list and select the initially selected device
update_device_list();
// connect(_device_bar, SIGNAL(device_selected()), this,
// SLOT(device_selected()));
connect(_device_bar, SIGNAL(device_selected()), this,
SLOT(init()));
SLOT(device_selected()));
// connect(_device_bar, SIGNAL(device_selected()), this,
// SLOT(init()));
connect(_device_bar, SIGNAL(device_updated()), this,
SLOT(update()));
connect(_sampling_bar, SIGNAL(device_reload()), this,
SLOT(init()));
connect(_sampling_bar, SIGNAL(run_stop()), this,
SLOT(run_stop()));
addToolBar(_sampling_bar);
@@ -298,7 +300,7 @@ void MainWindow::setup_ui()
addDockWidget(Qt::BottomDockWidgetArea, _search_dock);
// Set the title
setWindowTitle(QApplication::translate("MainWindow", "DSLogic", 0,
setWindowTitle(QApplication::translate("MainWindow", "DSLogic(Beta)", 0,
QApplication::UnicodeUTF8));
// Setup _session events
@@ -372,10 +374,10 @@ void MainWindow::update_device_list(struct sr_dev_inst *selected_device)
}
}
#ifdef HAVE_LA_DSLOGIC
_session.start_hot_plug_proc(boost::bind(&MainWindow::session_error, this,
// #ifdef HAVE_LA_DSLOGIC
_session.start_hotplug_proc(boost::bind(&MainWindow::session_error, this,
QString("Hotplug failed"), _1));
#endif
// #endif
}
void MainWindow::device_change()
@@ -408,11 +410,11 @@ void MainWindow::device_change()
device_detach();
}
#ifdef HAVE_LA_DSLOGIC
_session.stop_hot_plug_proc();
_session.start_hot_plug_proc(boost::bind(&MainWindow::session_error, this,
// #ifdef HAVE_LA_DSLOGIC
_session.stop_hotplug_proc();
_session.start_hotplug_proc(boost::bind(&MainWindow::session_error, this,
QString("Hotplug failed"), _1));
#endif
// #endif
}
@@ -453,7 +455,7 @@ void MainWindow::device_selected()
void MainWindow::device_attach()
{
_session.stop_hot_plug_proc();
_session.stop_hotplug_proc();
if (_session.get_capture_state() == SigSession::Running)
_session.stop_capture();
@@ -470,7 +472,7 @@ void MainWindow::device_attach()
void MainWindow::device_detach()
{
_session.stop_hot_plug_proc();
_session.stop_hotplug_proc();
if (_session.get_capture_state() == SigSession::Running)
_session.stop_capture();
@@ -508,6 +510,7 @@ void MainWindow::run_stop()
void MainWindow::test_data_error()
{
_session.stop_capture();
QMessageBox msg(this);
msg.setText("Data Error");
msg.setInformativeText("the receive data are not consist with pre-defined test data");

View File

@@ -84,6 +84,7 @@ DeviceOptions::DeviceOptions(struct sr_dev_inst *sdi) :
case SR_CONF_TRIGGER_SOURCE:
case SR_CONF_FILTER:
case SR_CONF_COUPLING:
case SR_CONF_OPERATION_MODE:
bind_enum(name, key, gvar_list);
break;

View File

@@ -26,11 +26,14 @@
#include "devicemanager.h"
#include "data/analog.h"
#include "data/analogsnapshot.h"
#include "data/dso.h"
#include "data/dsosnapshot.h"
#include "data/logic.h"
#include "data/logicsnapshot.h"
#include "data/group.h"
#include "data/groupsnapshot.h"
#include "view/analogsignal.h"
#include "view/dsosignal.h"
#include "view/logicsignal.h"
#include "view/groupsignal.h"
#include "view/protocolsignal.h"
@@ -59,11 +62,10 @@ SigSession::SigSession(DeviceManager &device_manager) :
_sdi(NULL),
_capture_state(Init),
_last_sample_rate(1),
_total_sample_len(1),
_hot_plug_handle(NULL)
_total_sample_len(1)
{
// TODO: This should not be necessary
_session = this;
_session = this;
_hot_attach = false;
_hot_detach = false;
_adv_trigger = false;
@@ -71,23 +73,26 @@ SigSession::SigSession(DeviceManager &device_manager) :
_protocol_cnt = 0;
_decoderFactory = new decoder::DecoderFactory();
ds_trigger_init();
register_hotplug_callback();
}
SigSession::~SigSession()
{
stop_capture();
stop_capture();
if (_sampling_thread.get())
_sampling_thread->join();
_sampling_thread.reset();
if (_sampling_thread.get())
_sampling_thread->join();
_sampling_thread.reset();
if (_hot_plug_handle)
stop_hot_plug_proc();
if (_hotplug_handle) {
stop_hotplug_proc();
deregister_hotplug_callback();
}
ds_trigger_destroy();
// TODO: This should not be necessary
_session = NULL;
// TODO: This should not be necessary
_session = NULL;
}
quint64 SigSession::get_last_sample_rate() const
@@ -102,7 +107,10 @@ quint64 SigSession::get_total_sample_len() const
void SigSession::set_total_sample_len(quint64 length)
{
_total_sample_len = length;
if (_sdi->mode == DSO)
_total_sample_len = 8 * 1024;
else
_total_sample_len = length;
}
struct sr_dev_inst* SigSession::get_device() const
@@ -145,6 +153,19 @@ void SigSession::save_file(const std::string &name){
const shared_ptr<pv::data::LogicSnapshot> &snapshot =
snapshots.front();
sr_session_save(name.c_str(), _sdi,
(unsigned char*)snapshot->get_data(),
snapshot->get_unit_size(),
snapshot->get_sample_count());
} else if (_sdi->mode == DSO){
const deque< shared_ptr<pv::data::DsoSnapshot> > &snapshots =
_dso_data->get_snapshots();
if (snapshots.empty())
return;
const shared_ptr<pv::data::DsoSnapshot> &snapshot =
snapshots.front();
sr_session_save(name.c_str(), _sdi,
(unsigned char*)snapshot->get_data(),
snapshot->get_unit_size(),
@@ -215,7 +236,6 @@ void SigSession::stop_capture()
{
if (get_capture_state() == Stopped)
return;
sr_session_stop();
// Check that sampling stopped
@@ -255,6 +275,24 @@ int SigSession::get_logic_probe_cnt(const sr_dev_inst *sdi)
return logic_probe_cnt;
}
int SigSession::get_dso_probe_cnt(const sr_dev_inst *sdi)
{
unsigned int dso_probe_cnt = 0;
for (const GSList *l = sdi->probes; l; l = l->next) {
const sr_probe *const probe = (const sr_probe *)l->data;
if (!probe->enabled)
continue;
switch(probe->type) {
case SR_PROBE_DSO:
dso_probe_cnt++;
break;
}
}
return dso_probe_cnt;
}
int SigSession::get_analog_probe_cnt(const sr_dev_inst *sdi)
{
unsigned int analog_probe_cnt = 0;
@@ -289,6 +327,18 @@ void* SigSession::get_buf(int& unit_size, uint64_t &length)
const shared_ptr<pv::data::LogicSnapshot> &snapshot =
snapshots.front();
unit_size = snapshot->get_unit_size();
length = snapshot->get_sample_count();
return snapshot->get_data();
} else if (_sdi->mode == DSO) {
const deque< shared_ptr<pv::data::DsoSnapshot> > &snapshots =
_dso_data->get_snapshots();
if (snapshots.empty())
return NULL;
const shared_ptr<pv::data::DsoSnapshot> &snapshot =
snapshots.front();
unit_size = snapshot->get_unit_size();
length = snapshot->get_sample_count();
return snapshot->get_data();
@@ -339,6 +389,7 @@ void SigSession::load_thread_proc(const string name,
// Confirm that SR_DF_END was received
assert(!_cur_logic_snapshot);
assert(!_cur_dso_snapshot);
assert(!_cur_analog_snapshot);
}
@@ -346,64 +397,61 @@ void SigSession::sample_thread_proc(struct sr_dev_inst *sdi,
uint64_t record_length,
function<void (const QString)> error_handler)
{
// while(1) {
assert(sdi);
assert(error_handler);
assert(sdi);
assert(error_handler);
if (!_adv_trigger) {
/* simple trigger check trigger_enable */
ds_trigger_set_en(false);
BOOST_FOREACH(const shared_ptr<view::Signal> s, _signals)
{
assert(s);
if (s->get_trig() != 0) {
ds_trigger_set_en(true);
s->set_trig(s->get_trig());
}
if (!_adv_trigger) {
/* simple trigger check trigger_enable */
ds_trigger_set_en(false);
BOOST_FOREACH(const shared_ptr<view::Signal> s, _signals)
{
assert(s);
if (s->get_trig() != 0) {
ds_trigger_set_en(true);
s->set_trig(s->get_trig());
}
} else {
/* advanced trigger check trigger_enable */
ds_trigger_set_en(true);
}
} else {
/* advanced trigger check trigger_enable */
ds_trigger_set_en(true);
}
sr_session_new();
sr_session_datafeed_callback_add(data_feed_in_proc, NULL);
sr_session_new();
sr_session_datafeed_callback_add(data_feed_in_proc, NULL);
if (sr_session_dev_add(sdi) != SR_OK) {
error_handler(tr("Failed to use device."));
sr_session_destroy();
return;
}
// Set the sample limit
if (sr_config_set(sdi, SR_CONF_LIMIT_SAMPLES,
g_variant_new_uint64(record_length)) != SR_OK) {
error_handler(tr("Failed to configure "
"time-based sample limit."));
sr_session_destroy();
return;
}
receive_data(0);
set_capture_state(Running);
if (sr_session_start() != SR_OK) {
error_handler(tr("Failed to start session."));
set_capture_state(Stopped);
return;
}
sr_session_run();
if (sr_session_dev_add(sdi) != SR_OK) {
error_handler(tr("Failed to use device."));
sr_session_destroy();
return;
}
// Set the sample limit
if (sr_config_set(sdi, SR_CONF_LIMIT_SAMPLES,
g_variant_new_uint64(record_length)) != SR_OK) {
error_handler(tr("Failed to configure "
"time-based sample limit."));
sr_session_destroy();
return;
}
receive_data(0);
set_capture_state(Running);
if (sr_session_start() != SR_OK) {
error_handler(tr("Failed to start session."));
set_capture_state(Stopped);
return;
}
// Confirm that SR_DF_END was received
assert(!_cur_logic_snapshot);
assert(!_cur_analog_snapshot);
sr_session_run();
sr_session_destroy();
// g_usleep(3000*1000);
// }
set_capture_state(Stopped);
// Confirm that SR_DF_END was received
assert(!_cur_logic_snapshot);
assert(!_cur_dso_snapshot);
assert(!_cur_analog_snapshot);
}
void SigSession::feed_in_header(const sr_dev_inst *sdi)
@@ -412,6 +460,7 @@ void SigSession::feed_in_header(const sr_dev_inst *sdi)
GVariant *gvar;
uint64_t sample_rate = 0;
unsigned int logic_probe_count = 0;
unsigned int dso_probe_count = 0;
unsigned int analog_probe_count = 0;
// Detect what data types we will receive
@@ -425,6 +474,10 @@ void SigSession::feed_in_header(const sr_dev_inst *sdi)
logic_probe_count++;
break;
case SR_PROBE_DSO:
dso_probe_count++;
break;
case SR_PROBE_ANALOG:
analog_probe_count++;
break;
@@ -471,6 +524,11 @@ void SigSession::feed_in_header(const sr_dev_inst *sdi)
assert(_group_data);
}
if (dso_probe_count != 0) {
_dso_data.reset(new data::Dso(dso_probe_count, sample_rate));
assert(_dso_data);
}
if (analog_probe_count != 0) {
_analog_data.reset(new data::Analog(analog_probe_count, sample_rate));
assert(_analog_data);
@@ -482,7 +540,7 @@ void SigSession::feed_in_header(const sr_dev_inst *sdi)
BOOST_FOREACH(const shared_ptr<view::Signal> s, _signals)
{
assert(s);
s->set_data(_logic_data, _analog_data, _group_data);
s->set_data(_logic_data, _dso_data, _analog_data, _group_data);
}
receive_data(0);
@@ -631,6 +689,7 @@ void SigSession::init_signals(const sr_dev_inst *sdi)
GVariant *gvar;
uint64_t sample_rate = 0;
unsigned int logic_probe_count = 0;
unsigned int dso_probe_count = 0;
unsigned int analog_probe_count = 0;
// Detect what data types we will receive
@@ -644,6 +703,10 @@ void SigSession::init_signals(const sr_dev_inst *sdi)
logic_probe_count++;
break;
case SR_PROBE_DSO:
dso_probe_count++;
break;
case SR_PROBE_ANALOG:
analog_probe_count++;
break;
@@ -680,6 +743,11 @@ void SigSession::init_signals(const sr_dev_inst *sdi)
_group_cnt = 0;
}
if (dso_probe_count != 0) {
_dso_data.reset(new data::Dso(dso_probe_count, sample_rate));
assert(_dso_data);
}
if (analog_probe_count != 0) {
_analog_data.reset(new data::Analog(analog_probe_count, sample_rate));
assert(_analog_data);
@@ -704,6 +772,12 @@ void SigSession::init_signals(const sr_dev_inst *sdi)
_logic_data, probe->index, _signals.size()));
break;
case SR_PROBE_DSO:
signal = shared_ptr<view::Signal>(
new view::DsoSignal(probe->name,
_dso_data, probe->index, _signals.size()));
break;
case SR_PROBE_ANALOG:
signal = shared_ptr<view::Signal>(
new view::AnalogSignal(probe->name,
@@ -728,7 +802,8 @@ void SigSession::update_signals(const sr_dev_inst *sdi)
std::vector< boost::shared_ptr<view::Signal> >::iterator i = _signals.begin();
while (i != _signals.end()) {
if (((*i)->get_type() == view::Signal::DS_LOGIC ||
(*i)->get_type() == view::Signal::DS_ANALOG))
(*i)->get_type() == view::Signal::DS_DSO ||
(*i)->get_type() == view::Signal::DS_ANALOG))
signals_en_table.insert((*i)->get_index(), 1);
i++;
}
@@ -753,6 +828,12 @@ void SigSession::update_signals(const sr_dev_inst *sdi)
_logic_data, probe->index, 0));
break;
case SR_PROBE_DSO:
signal = shared_ptr<view::Signal>(
new view::DsoSignal(probe->name,
_dso_data, probe->index, _signals.size()));
break;
case SR_PROBE_ANALOG:
signal = shared_ptr<view::Signal>(
new view::AnalogSignal(probe->name,
@@ -767,7 +848,8 @@ void SigSession::update_signals(const sr_dev_inst *sdi)
i = _signals.begin();
while (i != _signals.end()) {
if (((*i)->get_type() == view::Signal::DS_LOGIC ||
(*i)->get_type() == view::Signal::DS_ANALOG) &&
(*i)->get_type() == view::Signal::DS_DSO ||
(*i)->get_type() == view::Signal::DS_ANALOG) &&
probes_en_table.value((*i)->get_index()) == false) {
std::vector< boost::shared_ptr<view::Signal> >::iterator j = _signals.begin();
while(j != _signals.end()) {
@@ -845,6 +927,36 @@ void SigSession::feed_in_logic(const sr_datafeed_logic &logic)
//data_updated();
}
void SigSession::feed_in_dso(const sr_datafeed_dso &dso)
{
lock_guard<mutex> lock(_data_mutex);
if(!_dso_data)
{
qDebug() << "Unexpected dso packet";
return; // This dso packet was not expected.
}
if (!_cur_dso_snapshot)
{
// Create a new data snapshot
_cur_dso_snapshot = shared_ptr<data::DsoSnapshot>(
new data::DsoSnapshot(dso, _total_sample_len, _dso_data->get_num_probes()));
if (_cur_dso_snapshot->buf_null())
stop_capture();
else
_dso_data->push_snapshot(_cur_dso_snapshot);
}
else
{
// Append to the existing data snapshot
_cur_dso_snapshot->append_payload(dso);
}
receive_data(dso.num_samples);
data_updated();
}
void SigSession::feed_in_analog(const sr_datafeed_analog &analog)
{
lock_guard<mutex> lock(_data_mutex);
@@ -902,6 +1014,11 @@ void SigSession::data_feed_in(const struct sr_dev_inst *sdi,
feed_in_logic(*(const sr_datafeed_logic*)packet->payload);
break;
case SR_DF_DSO:
assert(packet->payload);
feed_in_dso(*(const sr_datafeed_dso*)packet->payload);
break;
case SR_DF_ANALOG:
assert(packet->payload);
feed_in_analog(*(const sr_datafeed_analog*)packet->payload);
@@ -926,6 +1043,7 @@ void SigSession::data_feed_in(const struct sr_dev_inst *sdi,
}
}
_cur_logic_snapshot.reset();
_cur_dso_snapshot.reset();
_cur_analog_snapshot.reset();
}
break;
@@ -1019,64 +1137,50 @@ QMap<QString, int> SigSession::get_decode_options_index(int decode_index)
/*
* hotplug function
*/
void SigSession::start_hot_plug_proc(boost::function<void (const QString)> error_handler)
{
#ifdef HAVE_LA_DSLOGIC
if (_hot_plug_handle) {
error_handler("Hotplug proc have started!");
return;
int SigSession::hotplug_callback(struct libusb_context *ctx, struct libusb_device *dev,
libusb_hotplug_event event, void *user_data) {
(void)ctx;
(void)dev;
(void)user_data;
if (LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED == event) {
_session->_hot_attach = true;
qDebug("DSLogic attaced!\n");
}else if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == event) {
_session->_hot_detach = true;
qDebug("DSLogic dettaced!\n");
}else{
qDebug("Unhandled event %d\n", event);
}
int ret = libusbhp_init(&_hot_plug_handle);
if(ret != 0) {
error_handler("Could not initialize hotplug handle.");
return;
}
libusbhp_register_hotplug_listeners(_hot_plug_handle,
dev_attach_callback,
dev_detach_callback,
NULL);
// Begin the session
_hot_plug.reset(new boost::thread(
&SigSession::hot_plug_proc, this, error_handler));
#else
error_handler("No hotplug device.");
#endif
return 0;
}
void SigSession::stop_hot_plug_proc()
void SigSession::hotplug_proc(boost::function<void (const QString)> error_handler)
{
#ifdef HAVE_LA_DSLOGIC
if (_hot_plug.get()) {
_hot_plug->interrupt();
_hot_plug->join();
}
_hot_plug.reset();
struct timeval tv;
if(_hot_plug_handle) {
libusbhp_exit(_hot_plug_handle);
_hot_plug_handle = NULL;
}
#endif
}
(void)error_handler;
void SigSession::hot_plug_proc(boost::function<void (const QString)> error_handler)
{
if (!_sdi)
return;
tv.tv_sec = tv.tv_usec = 0;
try {
while(_session) {
libusb_handle_events_timeout(NULL, &tv);
if (_hot_attach) {
qDebug("DSLogic hardware attached!");
device_attach();
_hot_attach = false;
break;
}
if (_hot_detach) {
qDebug("DSLogic hardware detached!");
device_detach();
_logic_data.reset();
_dso_data.reset();
_analog_data.reset();
_hot_detach = false;
break;
@@ -1085,39 +1189,51 @@ void SigSession::hot_plug_proc(boost::function<void (const QString)> error_handl
}
} catch(...) {
qDebug("Interrupt exception for hotplug thread was thrown.");
error_handler("Interrupt exception for hotplug thread was thrown.");
}
qDebug("Hotplug thread exit!");
}
void SigSession::dev_attach_callback(struct libusbhp_device_t *device, void *user_data)
void SigSession::register_hotplug_callback()
{
(void)user_data;
int ret;
if (device)
qDebug("Attach: (%04x/%04x)", device->idVendor, device->idProduct);
_session->_hot_attach = true;
ret = libusb_hotplug_register_callback(NULL, (libusb_hotplug_event)(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |
LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT),
(libusb_hotplug_flag)LIBUSB_HOTPLUG_ENUMERATE, 0x2A0E, 0x0001,
LIBUSB_HOTPLUG_MATCH_ANY, hotplug_callback, NULL,
&_hotplug_handle);
if (LIBUSB_SUCCESS != ret){
qDebug() << "Error creating a hotplug callback\n";
}
}
void SigSession::dev_detach_callback(struct libusbhp_device_t *device, void *user_data)
void SigSession::deregister_hotplug_callback()
{
(void)user_data;
if (device)
qDebug("Detach: (%04x/%04x)", device->idVendor, device->idProduct);
_session->_hot_detach = true;
libusb_hotplug_deregister_callback(NULL, _hotplug_handle);
}
int SigSession::hot_plug_active()
void SigSession::start_hotplug_proc(boost::function<void (const QString)> error_handler)
{
if (_hot_plug_handle)
return 1;
else
return 0;
// Begin the session
qDebug() << "Starting a hotplug thread...\n";
_hot_attach = false;
_hot_detach = false;
_hotplug.reset(new boost::thread(
&SigSession::hotplug_proc, this, error_handler));
}
void SigSession::stop_hotplug_proc()
{
if (_hotplug.get()) {
_hotplug->interrupt();
_hotplug->join();
}
_hotplug.reset();
}
/*
* Tigger
*/

View File

@@ -41,6 +41,7 @@
#include <QVariant>
#include <libsigrok4DSLogic/libsigrok.h>
#include <libusb.h>
namespace pv {
@@ -49,6 +50,8 @@ class DeviceManager;
namespace data {
class Analog;
class AnalogSnapshot;
class Dso;
class DsoSnapshot;
class Logic;
class LogicSnapshot;
class Group;
@@ -110,7 +113,7 @@ public:
get_pro_signals();
int get_logic_probe_cnt(const struct sr_dev_inst *sdi);
int get_dso_probe_cnt(const struct sr_dev_inst *sdi);
int get_analog_probe_cnt(const struct sr_dev_inst *sdi);
void init_signals(const struct sr_dev_inst *sdi);
@@ -147,9 +150,10 @@ public:
std::list<int> get_decode_probes(int decode_index);
QMap<QString, int> get_decode_options_index(int decode_index);
void start_hot_plug_proc(boost::function<void (const QString)> error_handler);
void stop_hot_plug_proc();
int hot_plug_active();
void start_hotplug_proc(boost::function<void (const QString)> error_handler);
void stop_hotplug_proc();
void register_hotplug_callback();
void deregister_hotplug_callback();
void set_adv_trigger(bool adv_trigger);
@@ -169,23 +173,21 @@ private:
void feed_in_meta(const sr_dev_inst *sdi,
const sr_datafeed_meta &meta);
void feed_in_trigger(const ds_trigger_pos &trigger_pos);
void feed_in_trigger(const ds_trigger_pos &trigger_pos);
void feed_in_logic(const sr_datafeed_logic &logic);
void feed_in_dso(const sr_datafeed_dso &dso);
void feed_in_analog(const sr_datafeed_analog &analog);
void data_feed_in(const struct sr_dev_inst *sdi,
const struct sr_datafeed_packet *packet);
const struct sr_datafeed_packet *packet);
static void data_feed_in_proc(const struct sr_dev_inst *sdi,
const struct sr_datafeed_packet *packet, void *cb_data);
static void data_feed_in_proc(const struct sr_dev_inst *sdi,
const struct sr_datafeed_packet *packet, void *cb_data);
void hot_plug_proc(boost::function<void (const QString)> error_handler);
static void dev_attach_callback(struct libusbhp_device_t *device, void *user_data);
static void dev_detach_callback(struct libusbhp_device_t *device, void *user_data);
void hotplug_proc(boost::function<void (const QString)> error_handler);
static int hotplug_callback(struct libusb_context *ctx, struct libusb_device *dev,
libusb_hotplug_event event, void *user_data);
private:
DeviceManager &_device_manager;
@@ -208,6 +210,8 @@ private:
mutable boost::mutex _data_mutex;
boost::shared_ptr<data::Logic> _logic_data;
boost::shared_ptr<data::LogicSnapshot> _cur_logic_snapshot;
boost::shared_ptr<data::Dso> _dso_data;
boost::shared_ptr<data::DsoSnapshot> _cur_dso_snapshot;
boost::shared_ptr<data::Analog> _analog_data;
boost::shared_ptr<data::AnalogSnapshot> _cur_analog_snapshot;
boost::shared_ptr<data::Group> _group_data;
@@ -221,8 +225,8 @@ private:
quint64 _total_sample_len;
struct libusbhp_t *_hot_plug_handle;
std::auto_ptr<boost::thread> _hot_plug;
libusb_hotplug_callback_handle _hotplug_handle;
std::auto_ptr<boost::thread> _hotplug;
bool _hot_attach;
bool _hot_detach;

View File

@@ -27,6 +27,8 @@
#include <boost/foreach.hpp>
#include <libsigrok4DSLogic/libsigrok.h>
#include <QAction>
#include <QDebug>
#include <QLabel>
@@ -63,24 +65,24 @@ const uint64_t SamplingBar::RecordLengths[19] = {
const uint64_t SamplingBar::DefaultRecordLength = 1000000;
const uint64_t SamplingBar::DSLogic_RecordLengths[15] = {
1000,
2000,
5000,
10000,
20000,
50000,
100000,
200000,
500000,
1000000,
2000000,
5000000,
10000000,
16000000,
100000000,
1024,
2048,
4096,
8192,
16384,
32768,
65536,
131072,
262144,
524288,
1048576,
2097152,
4194304,
8388608,
16777216,
};
const uint64_t SamplingBar::DSLogic_DefaultRecordLength = 16000000;
const uint64_t SamplingBar::DSLogic_DefaultRecordLength = 16777216;
SamplingBar::SamplingBar(QWidget *parent) :
QToolBar("Sampling Bar", parent),
@@ -131,7 +133,7 @@ void SamplingBar::set_device(struct sr_dev_inst *sdi)
for (size_t i = 0; i < countof(DSLogic_RecordLengths); i++)
{
const uint64_t &l = DSLogic_RecordLengths[i];
char *const text = sr_si_string_u64(l, " samples");
char *const text = sr_iec_string_u64(l, " samples");
_record_length_selector.addItem(QString(text),
qVariantFromValue(l));
g_free(text);
@@ -242,7 +244,9 @@ void SamplingBar::update_sample_rate_selector_value()
void SamplingBar::commit_sample_rate()
{
GVariant *gvar;
uint64_t sample_rate = 0;
uint64_t last_sample_rate = 0;
assert(_sdi);
@@ -259,12 +263,30 @@ void SamplingBar::commit_sample_rate()
if (sample_rate == 0)
return;
// Get last samplerate
if (sr_config_get(_sdi->driver, SR_CONF_SAMPLERATE,
&gvar, _sdi) != SR_OK) {
qDebug() <<
"WARNING: Failed to get value of sample rate";
return;
}
last_sample_rate = g_variant_get_uint64(gvar);
g_variant_unref(gvar);
// Set the samplerate
if (sr_config_set(_sdi, SR_CONF_SAMPLERATE,
g_variant_new_uint64(sample_rate)) != SR_OK) {
qDebug() << "Failed to configure samplerate.";
return;
}
if (strcmp(_sdi->driver->name, "DSLogic") == 0) {
if ((last_sample_rate == SR_MHZ(200)&& sample_rate != SR_MHZ(200)) ||
(last_sample_rate != SR_MHZ(200) && sample_rate == SR_MHZ(200)) ||
(last_sample_rate == SR_MHZ(400)&& sample_rate != SR_MHZ(400)) ||
(last_sample_rate != SR_MHZ(400) && sample_rate == SR_MHZ(400)))
device_reload();
}
}
void SamplingBar::on_sample_rate_changed()

View File

@@ -66,6 +66,7 @@ public:
signals:
void run_stop();
void device_reload();
private:
void update_sample_rate_selector_value();

View File

@@ -64,9 +64,11 @@ AnalogSignal::~AnalogSignal()
}
void AnalogSignal::set_data(boost::shared_ptr<data::Logic> _logic_data,
boost::shared_ptr<data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<data::Group> _group_data)
{
(void)_dso_data;
(void)_logic_data;
(void)_group_data;

View File

@@ -75,6 +75,7 @@ public:
void del_decoder();
void set_data(boost::shared_ptr<pv::data::Logic> _logic_data,
boost::shared_ptr<pv::data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<pv::data::Group> _group_data);

View File

@@ -0,0 +1,220 @@
/*
* This file is part of the DSLogic-gui project.
* DSLogic-gui is based on PulseView.
*
* Copyright (C) 2013 DreamSourceLab <dreamsourcelab@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 <extdef.h>
#include <math.h>
#include "dsosignal.h"
#include "pv/data/dso.h"
#include "pv/data/dsosnapshot.h"
using namespace boost;
using namespace std;
namespace pv {
namespace view {
const QColor DsoSignal::SignalColours[4] = {
QColor(17, 133, 209, 255), // dsBlue
QColor(238, 178, 17, 255), // dsYellow
QColor(213, 15, 37, 255), // dsRed
QColor(0, 153, 37, 255) // dsGreen
};
const float DsoSignal::EnvelopeThreshold = 256.0f;
DsoSignal::DsoSignal(QString name, shared_ptr<data::Dso> data,
int probe_index, int order) :
Signal(name, probe_index, DS_DSO, order),
_data(data)
{
_colour = SignalColours[probe_index % countof(SignalColours)];
_scale = _signalHeight * 1.0f / 256;
}
DsoSignal::~DsoSignal()
{
}
void DsoSignal::set_data(boost::shared_ptr<data::Logic> _logic_data,
boost::shared_ptr<data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<data::Group> _group_data)
{
(void)_analog_data;
(void)_logic_data;
(void)_group_data;
assert(_dso_data);
_data = _dso_data;
}
void DsoSignal::set_scale(float scale)
{
_scale = scale;
}
void DsoSignal::paint(QPainter &p, int y, int left, int right, double scale,
double offset)
{
assert(scale > 0);
assert(_data);
assert(right >= left);
//paint_axis(p, y, left, right);
const deque< shared_ptr<pv::data::DsoSnapshot> > &snapshots =
_data->get_snapshots();
if (snapshots.empty())
return;
_scale = _signalHeight * 1.0f / 256;
const shared_ptr<pv::data::DsoSnapshot> &snapshot =
snapshots.front();
if ((unsigned int)get_index() >= snapshot->get_channel_num())
return;
const double pixels_offset = offset / scale;
const double samplerate = _data->get_samplerate();
const double start_time = _data->get_start_time();
const int64_t last_sample = max((int64_t)(snapshot->get_sample_count() - 1), (int64_t)0);
const double samples_per_pixel = samplerate * scale;
const double start = samplerate * (offset - start_time);
const double end = start + samples_per_pixel * (right - left);
const int64_t start_sample = min(max((int64_t)floor(start),
(int64_t)0), last_sample);
const int64_t end_sample = min(max((int64_t)ceil(end) + 1,
(int64_t)0), last_sample);
if (samples_per_pixel < EnvelopeThreshold)
paint_trace(p, snapshot, y, left,
start_sample, end_sample,
pixels_offset, samples_per_pixel);
else
paint_envelope(p, snapshot, y, left,
start_sample, end_sample,
pixels_offset, samples_per_pixel);
}
void DsoSignal::paint_trace(QPainter &p,
const shared_ptr<pv::data::DsoSnapshot> &snapshot,
int y, int left, const int64_t start, const int64_t end,
const double pixels_offset, const double samples_per_pixel)
{
const int64_t sample_count = end - start;
if (sample_count > 0) {
const uint16_t *const samples = snapshot->get_samples(start, end);
assert(samples);
p.setPen(_colour);
//p.setPen(QPen(_colour, 3, Qt::SolidLine));
QPointF *points = new QPointF[sample_count];
QPointF *point = points;
for (int64_t sample = start; sample != end; sample++) {
const float x = (sample / samples_per_pixel - pixels_offset) + left;
uint16_t offset = samples[sample - start];
*point++ = QPointF(x,
y - ((get_index() == 0) ? offset & 0x00ff : offset >> 8) * _scale);
}
p.drawPolyline(points, point - points);
//delete[] samples;
delete[] points;
}
}
void DsoSignal::paint_envelope(QPainter &p,
const shared_ptr<pv::data::DsoSnapshot> &snapshot,
int y, int left, const int64_t start, const int64_t end,
const double pixels_offset, const double samples_per_pixel)
{
using namespace Qt;
using pv::data::DsoSnapshot;
DsoSnapshot::EnvelopeSection e;
snapshot->get_envelope_section(e, start, end, samples_per_pixel, get_index());
if (e.length < 2)
return;
p.setPen(QPen(NoPen));
//p.setPen(QPen(_colour, 2, Qt::SolidLine));
p.setBrush(_colour);
QRectF *const rects = new QRectF[e.length];
QRectF *rect = rects;
for(uint64_t sample = 0; sample < e.length-1; sample++) {
const float x = ((e.scale * sample + e.start) /
samples_per_pixel - pixels_offset) + left;
const DsoSnapshot::EnvelopeSample *const s =
e.samples + sample;
// We overlap this sample with the next so that vertical
// gaps do not appear during steep rising or falling edges
const float b = y - max(s->max, (s+1)->min) * _scale;
const float t = y - min(s->min, (s+1)->max) * _scale;
float h = b - t;
if(h >= 0.0f && h <= 1.0f)
h = 1.0f;
if(h <= 0.0f && h >= -1.0f)
h = -1.0f;
*rect++ = QRectF(x, t, 1.0f, h);
}
p.drawRects(rects, e.length);
delete[] rects;
//delete[] e.samples;
}
const std::vector< std::pair<uint64_t, bool> > DsoSignal::cur_edges() const
{
}
void DsoSignal::set_decoder(pv::decoder::Decoder *decoder)
{
(void)decoder;
}
decoder::Decoder *DsoSignal::get_decoder()
{
return NULL;
}
void DsoSignal::del_decoder()
{
}
} // namespace view
} // namespace pv

View File

@@ -0,0 +1,101 @@
/*
* This file is part of the DSLogic-gui project.
* DSLogic-gui is based on PulseView.
*
* Copyright (C) 2013 DreamSourceLab <dreamsourcelab@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 DSLOGIC_PV_DSOSIGNAL_H
#define DSLOGIC_PV_DSOSIGNAL_H
#include "signal.h"
#include <boost/shared_ptr.hpp>
namespace pv {
namespace data {
class Logic;
class Dso;
class Analog;
class DsoSnapshot;
}
namespace view {
class DsoSignal : public Signal
{
private:
static const QColor SignalColours[4];
static const float EnvelopeThreshold;
public:
DsoSignal(QString name,
boost::shared_ptr<pv::data::Dso> data, int probe_index, int order);
virtual ~DsoSignal();
void set_scale(float scale);
/**
* Paints the signal with a QPainter
* @param p the QPainter to paint into.
* @param y the y-coordinate to draw the signal at.
* @param left the x-coordinate of the left edge of the signal.
* @param right the x-coordinate of the right edge of the signal.
* @param scale the scale in seconds per pixel.
* @param offset the time to show at the left hand edge of
* the view in seconds.
**/
void paint(QPainter &p, int y, int left, int right, double scale,
double offset);
const std::vector< std::pair<uint64_t, bool> > cur_edges() const;
void set_decoder(pv::decoder::Decoder *decoder);
pv::decoder::Decoder* get_decoder();
void del_decoder();
void set_data(boost::shared_ptr<pv::data::Logic> _logic_data,
boost::shared_ptr<pv::data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<pv::data::Group> _group_data);
private:
void paint_trace(QPainter &p,
const boost::shared_ptr<pv::data::DsoSnapshot> &snapshot,
int y, int left, const int64_t start, const int64_t end,
const double pixels_offset, const double samples_per_pixel);
void paint_envelope(QPainter &p,
const boost::shared_ptr<pv::data::DsoSnapshot> &snapshot,
int y, int left, const int64_t start, const int64_t end,
const double pixels_offset, const double samples_per_pixel);
private:
boost::shared_ptr<pv::data::Dso> _data;
float _scale;
};
} // namespace view
} // namespace pv
#endif // DSLOGIC_PV_DSOSIGNAL_H

View File

@@ -58,10 +58,12 @@ GroupSignal::~GroupSignal()
}
void GroupSignal::set_data(boost::shared_ptr<data::Logic> _logic_data,
boost::shared_ptr<data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<data::Group> _group_data)
{
(void)_logic_data;
(void)_dso_data;
(void)_analog_data;
assert(_group_data);

View File

@@ -79,6 +79,7 @@ public:
void del_decoder();
void set_data(boost::shared_ptr<pv::data::Logic> _logic_data,
boost::shared_ptr<pv::data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<pv::data::Group> _group_data);

View File

@@ -147,7 +147,7 @@ void Header::paintEvent(QPaintEvent*)
w, s->get_old_v_offset() - v_offset - s->get_signalHeight());
painter.drawLine(0, s->get_old_v_offset() - v_offset,
w, s->get_old_v_offset() - v_offset);
} else {
} else if (s->get_type() == Signal::DS_LOGIC){
painter.drawLine(0, s->get_old_v_offset() - v_offset + 10,
w, s->get_old_v_offset() - v_offset + 10);
}
@@ -157,7 +157,7 @@ void Header::paintEvent(QPaintEvent*)
w, s->get_v_offset() - v_offset);
painter.drawLine(0, s->get_v_offset() - v_offset - s->get_signalHeight(),
w, s->get_v_offset() - v_offset - s->get_signalHeight());
} else {
} else if (s->get_type() == Signal::DS_LOGIC) {
painter.drawLine(0, s->get_v_offset() - v_offset + 10,
w, s->get_v_offset() - v_offset + 10);
}

View File

@@ -82,9 +82,11 @@ LogicSignal::~LogicSignal()
}
void LogicSignal::set_data(boost::shared_ptr<data::Logic> _logic_data,
boost::shared_ptr<data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<data::Group> _group_data)
{
(void)_dso_data;
(void)_analog_data;
(void)_group_data;

View File

@@ -62,6 +62,7 @@ public:
virtual ~LogicSignal();
void set_data(boost::shared_ptr<pv::data::Logic> _logic_data,
boost::shared_ptr<pv::data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<pv::data::Group> _group_data);
/**

View File

@@ -55,10 +55,11 @@ ProtocolSignal::~ProtocolSignal()
{
}
void ProtocolSignal::set_data(boost::shared_ptr<data::Logic> _logic_data,
void ProtocolSignal::set_data(boost::shared_ptr<data::Logic> _logic_data, boost::shared_ptr<data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<data::Group> _group_data)
{
(void)_dso_data;
(void)_analog_data;
(void)_group_data;

View File

@@ -57,6 +57,7 @@ public:
virtual ~ProtocolSignal();
void set_data(boost::shared_ptr<pv::data::Logic> _logic_data,
boost::shared_ptr<pv::data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<pv::data::Group> _group_data);

View File

@@ -42,6 +42,7 @@ namespace pv {
namespace data {
class SignalData;
class Logic;
class Dso;
class Analog;
class Group;
}
@@ -76,7 +77,7 @@ public:
static const QColor dsLightRed;
static const QPen SignalAxisPen;
enum {DS_LOGIC = 0, DS_ANALOG, DS_GROUP, DS_PROTOCOL};
enum {DS_LOGIC = 0, DS_ANALOG, DS_GROUP, DS_PROTOCOL, DS_DSO};
protected:
Signal(QString name, int index, int type, int order);
@@ -187,6 +188,7 @@ public:
virtual void del_decoder() = 0;
virtual void set_data(boost::shared_ptr<pv::data::Logic> _logic_data,
boost::shared_ptr<pv::data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<pv::data::Group> _group_data) = 0;

View File

@@ -95,7 +95,7 @@ void Viewport::paintEvent(QPaintEvent *event)
(void)event;
using pv::view::Signal;
int i, j;
QStyleOption o;
o.initFrom(this);
QPainter p(this);
@@ -118,7 +118,7 @@ void Viewport::paintEvent(QPaintEvent *event)
paintProgress(p);
break;
}
} else if (_view.session().get_device()->mode == ANALOG) {
} else {
paintSignals(p);
}
@@ -134,7 +134,6 @@ void Viewport::paintEvent(QPaintEvent *event)
p.setPen(Signal::dsGray);
const double sigY = s->get_v_offset() - _view.v_offset();
int i, j;
if (s->get_type() == Signal::DS_ANALOG) {
p.drawLine(0, sigY, width(), sigY);
const double spanY = (s->get_signalHeight()) * 1.0f / NumSpanY;
@@ -152,11 +151,39 @@ void Viewport::paintEvent(QPaintEvent *event)
p.drawLine(0 + spanX * i, sigY,
0 + spanX * i, sigY - s->get_signalHeight());
}
} else {
} else if (s->get_type() == Signal::DS_LOGIC) {
p.drawLine(0, sigY + 10, width(), sigY + 10);
}
}
if (_view.session().get_device()->mode == DSO) {
p.setPen(Signal::dsGray);
p.setPen(Qt::DotLine);
const double spanY =height() * 1.0f / 8;
for (i = 1; i < 9; i++) {
const double posY = spanY * i;
p.drawLine(0, posY, width(), posY);
const double miniSpanY = spanY / 5;
for (j = 1; j < 5; j++) {
p.drawLine(width() / 2.0f - 10, posY - miniSpanY * j,
width() / 2.0f + 10, posY - miniSpanY * j);
}
}
const double spanX = width() * 1.0f / 10;
for (i = 1; i < 11; i++) {
const double posX = spanX * i;
p.drawLine(posX, 0,
posX, height());
const double miniSpanX = spanX / 5;
for (j = 1; j < 5; j++) {
p.drawLine(posX - miniSpanX * j, height() / 2.0f - 10,
posX - miniSpanX * j, height() / 2.0f + 10);
}
}
}
p.end();
}