mirror of
https://github.com/DreamSourceLab/DSView.git
synced 2025-01-13 13:32:53 +08:00
v0.3
This commit is contained in:
parent
a6a3024de0
commit
95f2bf8964
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -85,8 +85,8 @@ set(DS_TITLE DSLogic)
|
||||
set(DS_DESCRIPTION "A GUI for DSLogic")
|
||||
|
||||
set(DS_VERSION_MAJOR 0)
|
||||
set(DS_VERSION_MINOR 2)
|
||||
set(DS_VERSION_MICRO 1)
|
||||
set(DS_VERSION_MINOR 3)
|
||||
set(DS_VERSION_MICRO 0)
|
||||
set(DS_VERSION_STRING
|
||||
${DS_VERSION_MAJOR}.${DS_VERSION_MINOR}.${DS_VERSION_MICRO}
|
||||
)
|
||||
@ -156,6 +156,8 @@ set(DSLogic_SOURCES
|
||||
pv/view/view.cpp
|
||||
pv/view/viewport.cpp
|
||||
pv/view/dsosignal.cpp
|
||||
pv/view/dsldial.cpp
|
||||
pv/dock/dsotriggerdock.cpp
|
||||
)
|
||||
|
||||
set(DSLogic_HEADERS
|
||||
@ -187,6 +189,8 @@ set(DSLogic_HEADERS
|
||||
pv/view/view.h
|
||||
pv/view/dsosignal.h
|
||||
pv/view/viewport.h
|
||||
pv/view/dsldial.h
|
||||
pv/dock/dsotriggerdock.h
|
||||
)
|
||||
|
||||
set(DSLogic_FORMS
|
||||
|
@ -1,49 +1,49 @@
|
||||
-------------------------------------------------------------------------------
|
||||
INSTALL
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
- git
|
||||
- g++
|
||||
- make
|
||||
- libtool
|
||||
- pkg-config >= 0.22
|
||||
- cmake >= 2.6
|
||||
- libglib >= 2.28.0
|
||||
- Qt >= 4.5
|
||||
- libboost >= 1.42 (including the following libs):
|
||||
- libboost-system
|
||||
- libboost-thread
|
||||
- libsigrok4DSLogic >= 0.2.0
|
||||
|
||||
|
||||
Building and installing
|
||||
-----------------------
|
||||
Get the DSLogic-gui source code from: www.dreamsourcelab.com/download.html
|
||||
In order to build it, run:
|
||||
|
||||
$ cd DSLogic-gui
|
||||
$ cmake .
|
||||
$ make
|
||||
|
||||
For installing PulseView:
|
||||
|
||||
$ make install
|
||||
|
||||
See the following wiki page for more (OS-specific) instructions:
|
||||
|
||||
http://sigrok.org/wiki/Building
|
||||
|
||||
|
||||
Creating a source distribution package
|
||||
--------------------------------------
|
||||
|
||||
In order to build a source package begin with an unconfigured source tree.
|
||||
|
||||
$ mkdir dist
|
||||
$ cd dist
|
||||
$ cmake ..
|
||||
$ make package_source
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
INSTALL
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
- git
|
||||
- g++
|
||||
- make
|
||||
- libtool
|
||||
- pkg-config >= 0.22
|
||||
- cmake >= 2.6
|
||||
- libglib >= 2.28.0
|
||||
- Qt >= 4.5
|
||||
- libboost >= 1.42 (including the following libs):
|
||||
- libboost-system
|
||||
- libboost-thread
|
||||
- libsigrok4DSLogic >= 0.2.0
|
||||
|
||||
|
||||
Building and installing
|
||||
-----------------------
|
||||
Get the DSLogic-gui source code from: www.dreamsourcelab.com/download.html
|
||||
In order to build it, run:
|
||||
|
||||
$ cd DSLogic-gui
|
||||
$ cmake .
|
||||
$ make
|
||||
|
||||
For installing PulseView:
|
||||
|
||||
$ make install
|
||||
|
||||
See the following wiki page for more (OS-specific) instructions:
|
||||
|
||||
http://sigrok.org/wiki/Building
|
||||
|
||||
|
||||
Creating a source distribution package
|
||||
--------------------------------------
|
||||
|
||||
In order to build a source package begin with an unconfigured source tree.
|
||||
|
||||
$ mkdir dist
|
||||
$ cd dist
|
||||
$ cmake ..
|
||||
$ make package_source
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
0.1.0 (2013-12-15)
|
||||
------------------
|
||||
|
||||
* Initial release.
|
||||
|
||||
0.1.0 (2013-12-15)
|
||||
------------------
|
||||
|
||||
* Initial release.
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
@ -1,3 +0,0 @@
|
||||
/usr/local/bin/DSLogic
|
||||
/usr/local/bin/res/DSLogic.fw
|
||||
/usr/local/bin/res/DSLogic.bin
|
28775
DSLogic-gui/ltrace.txt
28775
DSLogic-gui/ltrace.txt
File diff suppressed because it is too large
Load Diff
@ -70,8 +70,8 @@ void DsoSnapshot::append_payload(const sr_datafeed_dso &dso)
|
||||
append_payload_to_envelope_levels();
|
||||
}
|
||||
|
||||
const uint16_t* DsoSnapshot::get_samples(
|
||||
int64_t start_sample, int64_t end_sample) const
|
||||
const uint8_t *DsoSnapshot::get_samples(
|
||||
int64_t start_sample, int64_t end_sample, uint16_t index) const
|
||||
{
|
||||
assert(start_sample >= 0);
|
||||
assert(start_sample < (int64_t)get_sample_count());
|
||||
@ -85,7 +85,7 @@ const uint16_t* DsoSnapshot::get_samples(
|
||||
// memcpy(data, (uint16_t*)_data + start_sample, sizeof(uint16_t) *
|
||||
// (end_sample - start_sample));
|
||||
// return data;
|
||||
return (uint16_t*)_data + start_sample;
|
||||
return (uint8_t*)_data + start_sample * _channel_num + index;
|
||||
}
|
||||
|
||||
void DsoSnapshot::get_envelope_section(EnvelopeSection &s,
|
||||
@ -150,7 +150,7 @@ void DsoSnapshot::append_payload_to_envelope_levels()
|
||||
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 +
|
||||
const uint8_t *const stop_src_ptr = (uint8_t*)_data +
|
||||
e0.length * EnvelopeScaleFactor * _channel_num;
|
||||
// for (const uint16_t *src_ptr = (uint16_t*)_data +
|
||||
// prev_length * EnvelopeScaleFactor;
|
||||
@ -163,13 +163,13 @@ void DsoSnapshot::append_payload_to_envelope_levels()
|
||||
|
||||
// *dest_ptr++ = sub_sample;
|
||||
// }
|
||||
for (const uint16_t *src_ptr = (uint16_t*)_data +
|
||||
for (const uint8_t *src_ptr = (uint8_t*)_data +
|
||||
prev_length * EnvelopeScaleFactor * _channel_num + i;
|
||||
src_ptr < stop_src_ptr; src_ptr += EnvelopeScaleFactor * _channel_num)
|
||||
{
|
||||
const uint16_t * begin_src_ptr =
|
||||
const uint8_t * begin_src_ptr =
|
||||
src_ptr;
|
||||
const uint16_t *const end_src_ptr =
|
||||
const uint8_t *const end_src_ptr =
|
||||
src_ptr + EnvelopeScaleFactor * _channel_num;
|
||||
|
||||
EnvelopeSample sub_sample;
|
||||
|
@ -40,8 +40,8 @@ class DsoSnapshot : public Snapshot
|
||||
public:
|
||||
struct EnvelopeSample
|
||||
{
|
||||
uint16_t min;
|
||||
uint16_t max;
|
||||
uint8_t min;
|
||||
uint8_t max;
|
||||
};
|
||||
|
||||
struct EnvelopeSection
|
||||
@ -74,8 +74,8 @@ public:
|
||||
|
||||
void append_payload(const sr_datafeed_dso &dso);
|
||||
|
||||
const uint16_t* get_samples(int64_t start_sample,
|
||||
int64_t end_sample) const;
|
||||
const uint8_t* get_samples(int64_t start_sample,
|
||||
int64_t end_sample, uint16_t index) const;
|
||||
|
||||
void get_envelope_section(EnvelopeSection &s,
|
||||
uint64_t start, uint64_t end, float min_length, int probe_index) const;
|
||||
|
@ -194,6 +194,7 @@ void DeviceOptions::disable_all_probes()
|
||||
|
||||
void DeviceOptions::mode_changed(QString mode)
|
||||
{
|
||||
(void)mode;
|
||||
// Commit mode
|
||||
sr_config_set(_sdi, SR_CONF_DEVICE_MODE, g_variant_new_string(_mode_comboBox.currentText().toLocal8Bit()));
|
||||
setup_probes();
|
||||
|
196
DSLogic-gui/pv/dock/dsotriggerdock.cpp
Normal file
196
DSLogic-gui/pv/dock/dsotriggerdock.cpp
Normal file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
* This file is part of the DSLogic-gui project.
|
||||
* DSLogic-gui is based on PulseView.
|
||||
*
|
||||
* Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
|
||||
* 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 "dsotriggerdock.h"
|
||||
#include "../sigsession.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QLabel>
|
||||
#include <QRadioButton>
|
||||
#include <QPainter>
|
||||
#include <QStyleOption>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <QVector>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
|
||||
#include "libsigrok4DSLogic/libsigrok.h"
|
||||
|
||||
namespace pv {
|
||||
namespace dock {
|
||||
|
||||
DsoTriggerDock::DsoTriggerDock(QWidget *parent, SigSession &session) :
|
||||
QWidget(parent),
|
||||
_session(session)
|
||||
{
|
||||
QLabel *position_label = new QLabel("Trigger Position: ", this);
|
||||
position_spinBox = new QSpinBox(this);
|
||||
position_spinBox->setRange(0, 99);
|
||||
position_spinBox->setButtonSymbols(QAbstractSpinBox::NoButtons);
|
||||
position_slider = new QSlider(Qt::Horizontal, this);
|
||||
position_slider->setRange(0, 99);
|
||||
connect(position_slider, SIGNAL(valueChanged(int)), position_spinBox, SLOT(setValue(int)));
|
||||
connect(position_spinBox, SIGNAL(valueChanged(int)), position_slider, SLOT(setValue(int)));
|
||||
connect(position_slider, SIGNAL(valueChanged(int)), this, SLOT(pos_changed(int)));
|
||||
|
||||
QLabel *tSource_labe = new QLabel("Trigger Sources: ", this);
|
||||
QRadioButton *auto_radioButton = new QRadioButton("Auto");
|
||||
auto_radioButton->setChecked(true);
|
||||
QRadioButton *ch0_radioButton = new QRadioButton("Channel 0");
|
||||
QRadioButton *ch1_radioButton = new QRadioButton("Channel 1");
|
||||
QRadioButton *ch0a1_radioButton = new QRadioButton("Channel 0 && Channel 1");
|
||||
QRadioButton *ch0o1_radioButton = new QRadioButton("Channel 0 | Channel 1");
|
||||
connect(auto_radioButton, SIGNAL(clicked()), this, SLOT(source_changed()));
|
||||
connect(ch0_radioButton, SIGNAL(clicked()), this, SLOT(source_changed()));
|
||||
connect(ch1_radioButton, SIGNAL(clicked()), this, SLOT(source_changed()));
|
||||
connect(ch0a1_radioButton, SIGNAL(clicked()), this, SLOT(source_changed()));
|
||||
connect(ch0o1_radioButton, SIGNAL(clicked()), this, SLOT(source_changed()));
|
||||
|
||||
QLabel *tType_labe = new QLabel("Trigger Types: ", this);
|
||||
QRadioButton *rising_radioButton = new QRadioButton("Rising Edge");
|
||||
rising_radioButton->setChecked(true);
|
||||
QRadioButton *falling_radioButton = new QRadioButton("Falling Edge");
|
||||
connect(rising_radioButton, SIGNAL(clicked()), this, SLOT(type_changed()));
|
||||
connect(falling_radioButton, SIGNAL(clicked()), this, SLOT(type_changed()));
|
||||
|
||||
source_group=new QButtonGroup(this);
|
||||
type_group=new QButtonGroup(this);
|
||||
|
||||
source_group->addButton(auto_radioButton);
|
||||
source_group->addButton(ch0_radioButton);
|
||||
source_group->addButton(ch1_radioButton);
|
||||
source_group->addButton(ch0a1_radioButton);
|
||||
source_group->addButton(ch0o1_radioButton);
|
||||
source_group->setId(auto_radioButton, DSO_TRIGGER_AUTO);
|
||||
source_group->setId(ch0_radioButton, DSO_TRIGGER_CH0);
|
||||
source_group->setId(ch1_radioButton, DSO_TRIGGER_CH1);
|
||||
source_group->setId(ch0a1_radioButton, DSO_TRIGGER_CH0A1);
|
||||
source_group->setId(ch0o1_radioButton, DSO_TRIGGER_CH0O1);
|
||||
|
||||
type_group->addButton(rising_radioButton);
|
||||
type_group->addButton(falling_radioButton);
|
||||
type_group->setId(rising_radioButton, DSO_TRIGGER_RISING);
|
||||
type_group->setId(falling_radioButton, DSO_TRIGGER_FALLING);
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
QGridLayout *gLayout = new QGridLayout();
|
||||
gLayout->addWidget(position_label, 0, 0);
|
||||
gLayout->addWidget(position_spinBox, 0, 1);
|
||||
gLayout->addWidget(new QLabel(this), 0, 2);
|
||||
gLayout->addWidget(position_slider, 1, 0, 1, 3);
|
||||
|
||||
gLayout->addWidget(new QLabel(this), 2, 0);
|
||||
gLayout->addWidget(tSource_labe, 3, 0);
|
||||
gLayout->addWidget(auto_radioButton, 4, 0);
|
||||
gLayout->addWidget(ch0_radioButton, 5, 0);
|
||||
gLayout->addWidget(ch1_radioButton, 5, 1);
|
||||
gLayout->addWidget(ch0a1_radioButton, 6, 0);
|
||||
gLayout->addWidget(ch0o1_radioButton, 6, 1);
|
||||
|
||||
gLayout->addWidget(new QLabel(this), 7, 0);
|
||||
gLayout->addWidget(tType_labe, 8, 0);
|
||||
gLayout->addWidget(rising_radioButton, 9, 0);
|
||||
gLayout->addWidget(falling_radioButton, 10, 0);
|
||||
|
||||
gLayout->setColumnStretch(3, 1);
|
||||
|
||||
layout->addLayout(gLayout);
|
||||
layout->addStretch(1);
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
DsoTriggerDock::~DsoTriggerDock()
|
||||
{
|
||||
}
|
||||
|
||||
void DsoTriggerDock::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QStyleOption opt;
|
||||
opt.init(this);
|
||||
QPainter p(this);
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
}
|
||||
|
||||
void DsoTriggerDock::pos_changed(int pos)
|
||||
{
|
||||
int ret;
|
||||
quint32 real_pos;
|
||||
real_pos = pos*_session.get_total_sample_len()/100.0f;
|
||||
real_pos = (_session.get_last_sample_rate() > SR_MHZ(100)) ? real_pos/2 : real_pos;
|
||||
ret = sr_config_set(_session.get_device(), SR_CONF_HORIZ_TRIGGERPOS, g_variant_new_uint32(real_pos));
|
||||
if (ret != SR_OK) {
|
||||
QMessageBox msg(this);
|
||||
msg.setText("Trigger Setting Issue");
|
||||
msg.setInformativeText("Change horiz trigger position failed!");
|
||||
msg.setStandardButtons(QMessageBox::Ok);
|
||||
msg.setIcon(QMessageBox::Warning);
|
||||
msg.exec();
|
||||
}
|
||||
}
|
||||
|
||||
void DsoTriggerDock::source_changed()
|
||||
{
|
||||
int id = source_group->checkedId();
|
||||
int ret;
|
||||
|
||||
ret = sr_config_set(_session.get_device(), SR_CONF_TRIGGER_SOURCE, g_variant_new_byte(id));
|
||||
if (ret != SR_OK) {
|
||||
QMessageBox msg(this);
|
||||
msg.setText("Trigger Setting Issue");
|
||||
msg.setInformativeText("Change trigger source failed!");
|
||||
msg.setStandardButtons(QMessageBox::Ok);
|
||||
msg.setIcon(QMessageBox::Warning);
|
||||
msg.exec();
|
||||
}
|
||||
}
|
||||
|
||||
void DsoTriggerDock::type_changed()
|
||||
{
|
||||
int id = type_group->checkedId();
|
||||
int ret;
|
||||
|
||||
ret = sr_config_set(_session.get_device(), SR_CONF_TRIGGER_SLOPE, g_variant_new_byte(id));
|
||||
if (ret != SR_OK) {
|
||||
QMessageBox msg(this);
|
||||
msg.setText("Trigger Setting Issue");
|
||||
msg.setInformativeText("Change trigger type failed!");
|
||||
msg.setStandardButtons(QMessageBox::Ok);
|
||||
msg.setIcon(QMessageBox::Warning);
|
||||
msg.exec();
|
||||
}
|
||||
}
|
||||
|
||||
void DsoTriggerDock::device_change()
|
||||
{
|
||||
if (strcmp(_session.get_device()->driver->name, "DSLogic") != 0) {
|
||||
position_spinBox->setDisabled(true);
|
||||
position_slider->setDisabled(true);
|
||||
} else {
|
||||
position_spinBox->setDisabled(false);
|
||||
position_slider->setDisabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dock
|
||||
} // namespace pv
|
76
DSLogic-gui/pv/dock/dsotriggerdock.h
Normal file
76
DSLogic-gui/pv/dock/dsotriggerdock.h
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* This file is part of the DSLogic-gui project.
|
||||
* DSLogic-gui is based on PulseView.
|
||||
*
|
||||
* Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
|
||||
* 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_DSOTRIGGERDOCK_H
|
||||
#define DSLOGIC_PV_DSOTRIGGERDOCK_H
|
||||
|
||||
#include <QDockWidget>
|
||||
#include <QSlider>
|
||||
#include <QSpinBox>
|
||||
#include <QButtonGroup>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <libsigrok4DSLogic/libsigrok.h>
|
||||
|
||||
namespace pv {
|
||||
|
||||
class SigSession;
|
||||
|
||||
namespace dock {
|
||||
|
||||
class DsoTriggerDock : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DsoTriggerDock(QWidget *parent, SigSession &session);
|
||||
~DsoTriggerDock();
|
||||
|
||||
void paintEvent(QPaintEvent *);
|
||||
|
||||
void device_change();
|
||||
|
||||
signals:
|
||||
|
||||
private slots:
|
||||
void pos_changed(int pos);
|
||||
void source_changed();
|
||||
void type_changed();
|
||||
|
||||
private:
|
||||
|
||||
private:
|
||||
SigSession &_session;
|
||||
|
||||
QSpinBox *position_spinBox;
|
||||
QSlider *position_slider;
|
||||
|
||||
QButtonGroup *source_group;
|
||||
QButtonGroup *type_group;
|
||||
};
|
||||
|
||||
} // namespace dock
|
||||
} // namespace pv
|
||||
|
||||
#endif // DSLOGIC_PV_DSOTRIGGERDOCK_H
|
@ -57,6 +57,7 @@
|
||||
|
||||
#include "dock/protocoldock.h"
|
||||
#include "dock/triggerdock.h"
|
||||
#include "dock/dsotriggerdock.h"
|
||||
#include "dock/measuredock.h"
|
||||
#include "dock/searchdock.h"
|
||||
|
||||
@ -235,6 +236,14 @@ void MainWindow::setup_ui()
|
||||
_trigger_widget = new dock::TriggerDock(_trigger_dock, _session);
|
||||
_trigger_dock->setWidget(_trigger_widget);
|
||||
|
||||
_dso_trigger_dock=new QDockWidget(tr("Trigger Setting..."),this);
|
||||
_dso_trigger_dock->setFeatures(QDockWidget::NoDockWidgetFeatures);
|
||||
_dso_trigger_dock->setAllowedAreas(Qt::RightDockWidgetArea);
|
||||
_dso_trigger_dock->setVisible(false);
|
||||
_dso_trigger_widget = new dock::DsoTriggerDock(_dso_trigger_dock, _session);
|
||||
_dso_trigger_dock->setWidget(_dso_trigger_widget);
|
||||
|
||||
|
||||
// Setup _view widget
|
||||
_view = new pv::view::View(_session, this);
|
||||
_vertical_layout->addWidget(_view);
|
||||
@ -250,9 +259,9 @@ void MainWindow::setup_ui()
|
||||
SLOT(update()));
|
||||
connect(_sampling_bar, SIGNAL(device_reload()), this,
|
||||
SLOT(init()));
|
||||
connect(_sampling_bar, SIGNAL(run_stop()), this,
|
||||
SLOT(run_stop()));
|
||||
addToolBar(_sampling_bar);
|
||||
connect(_sampling_bar, SIGNAL(run_stop()), this,
|
||||
SLOT(run_stop()));
|
||||
addToolBar(_sampling_bar);
|
||||
addToolBar(_trig_bar);
|
||||
addToolBar(_device_bar);
|
||||
addToolBar(_file_bar);
|
||||
@ -296,6 +305,7 @@ void MainWindow::setup_ui()
|
||||
_trigger_dock->setObjectName(tr("triggerDock"));
|
||||
addDockWidget(Qt::RightDockWidgetArea,_protocol_dock);
|
||||
addDockWidget(Qt::RightDockWidgetArea,_trigger_dock);
|
||||
addDockWidget(Qt::RightDockWidgetArea,_dso_trigger_dock);
|
||||
addDockWidget(Qt::RightDockWidgetArea, _measure_dock);
|
||||
addDockWidget(Qt::BottomDockWidgetArea, _search_dock);
|
||||
|
||||
@ -312,6 +322,8 @@ void MainWindow::setup_ui()
|
||||
SLOT(device_detach()));
|
||||
connect(&_session, SIGNAL(test_data_error()), this,
|
||||
SLOT(test_data_error()));
|
||||
connect(&_session, SIGNAL(dso_ch_changed(uint16_t)), this,
|
||||
SLOT(dso_ch_changed(uint16_t)));
|
||||
|
||||
connect(_view, SIGNAL(cursor_update()), _measure_widget,
|
||||
SLOT(cursor_update()));
|
||||
@ -327,6 +339,14 @@ void MainWindow::init()
|
||||
_trigger_widget->device_change();
|
||||
if (_session.get_device())
|
||||
_session.init_signals(_session.get_device());
|
||||
if (_session.get_device()->mode == DSO) {
|
||||
_sampling_bar->set_record_length(DefaultDSODepth*2);
|
||||
_sampling_bar->set_sample_rate(DefaultDSORate*2);
|
||||
_sampling_bar->enable_toggle(false);
|
||||
_view->hDial_changed(0);
|
||||
} else if(_session.get_device()->mode == LOGIC) {
|
||||
_sampling_bar->enable_toggle(true);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::update()
|
||||
@ -377,6 +397,8 @@ void MainWindow::update_device_list(struct sr_dev_inst *selected_device)
|
||||
// #ifdef HAVE_LA_DSLOGIC
|
||||
_session.start_hotplug_proc(boost::bind(&MainWindow::session_error, this,
|
||||
QString("Hotplug failed"), _1));
|
||||
_session.start_dso_ctrl_proc(boost::bind(&MainWindow::session_error, this,
|
||||
QString("Hotplug failed"), _1));
|
||||
// #endif
|
||||
}
|
||||
|
||||
@ -446,11 +468,39 @@ void MainWindow::device_selected()
|
||||
_sampling_bar->set_device(_device_bar->get_selected_device());
|
||||
_sampling_bar->update_sample_rate_selector();
|
||||
_view->show_trig_cursor(false);
|
||||
_trigger_dock->setVisible(false);
|
||||
_dso_trigger_dock->setVisible(false);
|
||||
_protocol_dock->setVisible(false);
|
||||
_measure_dock->setVisible(false);
|
||||
_search_dock->setVisible(false);
|
||||
init();
|
||||
} else {
|
||||
show_session_error("Open Device Failed",
|
||||
"the selected device can't be opened!");
|
||||
}
|
||||
|
||||
if (_device_bar->get_selected_device()->mode == DSO) {
|
||||
QMessageBox msg(this);
|
||||
msg.setText("Zero Adjustment");
|
||||
msg.setInformativeText("Please left both of channels unconnect for zero adjustment!");
|
||||
msg.setStandardButtons(QMessageBox::Ok);
|
||||
msg.setIcon(QMessageBox::Warning);
|
||||
msg.exec();
|
||||
|
||||
int ret = sr_config_set(_device_bar->get_selected_device(), SR_CONF_ZERO, g_variant_new_boolean(TRUE));
|
||||
if (ret != SR_OK) {
|
||||
QMessageBox msg(this);
|
||||
msg.setText("Zero Adjustment Issue");
|
||||
msg.setInformativeText("Can't send out the command of zero adjustment!");
|
||||
msg.setStandardButtons(QMessageBox::Ok);
|
||||
msg.setIcon(QMessageBox::Warning);
|
||||
msg.exec();
|
||||
} else {
|
||||
run_stop();
|
||||
g_usleep(100000);
|
||||
run_stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::device_attach()
|
||||
@ -508,6 +558,31 @@ void MainWindow::run_stop()
|
||||
_sampling_bar->enable_run_stop(true);
|
||||
}
|
||||
|
||||
void MainWindow::dso_ch_changed(uint16_t num)
|
||||
{
|
||||
if(num == 1) {
|
||||
_sampling_bar->set_record_length(DefaultDSODepth*2);
|
||||
_sampling_bar->set_sample_rate(DefaultDSORate*2);
|
||||
_session.set_total_sample_len(_sampling_bar->get_record_length());
|
||||
if (_session.get_capture_state() == SigSession::Running) {
|
||||
_session.stop_capture();
|
||||
_session.start_capture(_sampling_bar->get_record_length(),
|
||||
boost::bind(&MainWindow::session_error, this,
|
||||
QString("Capture failed"), _1));
|
||||
}
|
||||
} else {
|
||||
_sampling_bar->set_record_length(DefaultDSODepth);
|
||||
_sampling_bar->set_sample_rate(DefaultDSORate);
|
||||
_session.set_total_sample_len(_sampling_bar->get_record_length());
|
||||
if (_session.get_capture_state() == SigSession::Running) {
|
||||
_session.stop_capture();
|
||||
_session.start_capture(_sampling_bar->get_record_length(),
|
||||
boost::bind(&MainWindow::session_error, this,
|
||||
QString("Capture failed"), _1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::test_data_error()
|
||||
{
|
||||
_session.stop_capture();
|
||||
@ -521,12 +596,14 @@ void MainWindow::test_data_error()
|
||||
|
||||
void MainWindow::capture_state_changed(int state)
|
||||
{
|
||||
_sampling_bar->enable_toggle(state != SigSession::Running);
|
||||
_trig_bar->enable_toggle(state != SigSession::Running);
|
||||
if (_session.get_device()->mode != DSO) {
|
||||
_sampling_bar->enable_toggle(state != SigSession::Running);
|
||||
_trig_bar->enable_toggle(state != SigSession::Running);
|
||||
_measure_dock->widget()->setEnabled(state != SigSession::Running);
|
||||
}
|
||||
_device_bar->enable_toggle(state != SigSession::Running);
|
||||
_file_bar->enable_toggle(state != SigSession::Running);
|
||||
_sampling_bar->set_sampling(state == SigSession::Running);
|
||||
_measure_dock->widget()->setEnabled(state != SigSession::Running);
|
||||
_view->on_state_changed(state != SigSession::Running);
|
||||
}
|
||||
|
||||
@ -537,7 +614,10 @@ void MainWindow::on_protocol(bool visible)
|
||||
|
||||
void MainWindow::on_trigger(bool visible)
|
||||
{
|
||||
_trigger_dock->setVisible(visible);
|
||||
if (_session.get_device()->mode != DSO)
|
||||
_trigger_dock->setVisible(visible);
|
||||
else
|
||||
_dso_trigger_dock->setVisible(visible);
|
||||
}
|
||||
|
||||
void MainWindow::on_measure(bool visible)
|
||||
|
@ -54,6 +54,7 @@ class LogoBar;
|
||||
namespace dock{
|
||||
class ProtocolDock;
|
||||
class TriggerDock;
|
||||
class DsoTriggerDock;
|
||||
class MeasureDock;
|
||||
class SearchDock;
|
||||
}
|
||||
@ -66,6 +67,10 @@ class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
static const int DefaultDSODepth = 8192;
|
||||
static const int DefaultDSORate = 100000000;
|
||||
|
||||
public:
|
||||
explicit MainWindow(DeviceManager &device_manager,
|
||||
const char *open_file_name = NULL,
|
||||
@ -122,6 +127,9 @@ private slots:
|
||||
void device_attach();
|
||||
void device_detach();
|
||||
|
||||
/* */
|
||||
void dso_ch_changed(uint16_t num);
|
||||
|
||||
private:
|
||||
DeviceManager &_device_manager;
|
||||
|
||||
@ -155,7 +163,9 @@ private:
|
||||
QDockWidget *_protocol_dock;
|
||||
dock::ProtocolDock *_protocol_widget;
|
||||
QDockWidget *_trigger_dock;
|
||||
QDockWidget *_dso_trigger_dock;
|
||||
dock::TriggerDock *_trigger_widget;
|
||||
dock::DsoTriggerDock *_dso_trigger_widget;
|
||||
QDockWidget *_measure_dock;
|
||||
QDockWidget *_search_dock;
|
||||
dock::SearchDock * _search_widget;
|
||||
|
@ -83,8 +83,12 @@ DeviceOptions::DeviceOptions(struct sr_dev_inst *sdi) :
|
||||
case SR_CONF_BUFFERSIZE:
|
||||
case SR_CONF_TRIGGER_SOURCE:
|
||||
case SR_CONF_FILTER:
|
||||
case SR_CONF_COUPLING:
|
||||
case SR_CONF_COUPLING0:
|
||||
case SR_CONF_COUPLING1:
|
||||
case SR_CONF_EN_CH0:
|
||||
case SR_CONF_EN_CH1:
|
||||
case SR_CONF_OPERATION_MODE:
|
||||
case SR_CONF_ZERO:
|
||||
bind_enum(name, key, gvar_list);
|
||||
break;
|
||||
|
||||
@ -100,9 +104,12 @@ DeviceOptions::DeviceOptions(struct sr_dev_inst *sdi) :
|
||||
bind_enum(name, key, gvar_list, print_timebase);
|
||||
break;
|
||||
|
||||
case SR_CONF_VDIV:
|
||||
case SR_CONF_VDIV0:
|
||||
case SR_CONF_VDIV1:
|
||||
bind_enum(name, key, gvar_list, print_vdiv);
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
gvar_list = NULL;
|
||||
}
|
||||
|
||||
if (gvar_list)
|
||||
|
@ -65,7 +65,7 @@ SigSession::SigSession(DeviceManager &device_manager) :
|
||||
_total_sample_len(1)
|
||||
{
|
||||
// TODO: This should not be necessary
|
||||
_session = this;
|
||||
_session = this;
|
||||
_hot_attach = false;
|
||||
_hot_detach = false;
|
||||
_adv_trigger = false;
|
||||
@ -73,7 +73,11 @@ SigSession::SigSession(DeviceManager &device_manager) :
|
||||
_protocol_cnt = 0;
|
||||
_decoderFactory = new decoder::DecoderFactory();
|
||||
ds_trigger_init();
|
||||
register_hotplug_callback();
|
||||
|
||||
_vDial_changed = false;
|
||||
_hDial_changed = false;
|
||||
_dso_ctrl_channel = 0;
|
||||
register_hotplug_callback();
|
||||
}
|
||||
|
||||
SigSession::~SigSession()
|
||||
@ -90,9 +94,10 @@ SigSession::~SigSession()
|
||||
}
|
||||
|
||||
ds_trigger_destroy();
|
||||
stop_dso_ctrl_proc();
|
||||
|
||||
// TODO: This should not be necessary
|
||||
_session = NULL;
|
||||
// TODO: This should not be necessary
|
||||
_session = NULL;
|
||||
}
|
||||
|
||||
quint64 SigSession::get_last_sample_rate() const
|
||||
@ -107,10 +112,7 @@ quint64 SigSession::get_total_sample_len() const
|
||||
|
||||
void SigSession::set_total_sample_len(quint64 length)
|
||||
{
|
||||
if (_sdi->mode == DSO)
|
||||
_total_sample_len = 8 * 1024;
|
||||
else
|
||||
_total_sample_len = length;
|
||||
_total_sample_len = length;
|
||||
}
|
||||
|
||||
struct sr_dev_inst* SigSession::get_device() const
|
||||
@ -223,12 +225,28 @@ void SigSession::start_capture(uint64_t record_length,
|
||||
if (probe->enabled)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!l) {
|
||||
error_handler(tr("No probes enabled."));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check that at least one signal channel is active under DSO mode
|
||||
if (_sdi->mode == DSO) {
|
||||
bool active = false;
|
||||
BOOST_FOREACH(const shared_ptr<view::Signal> s, _signals)
|
||||
{
|
||||
assert(s);
|
||||
if (s->get_active()) {
|
||||
active = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!active) {
|
||||
error_handler(tr("No channels enabled."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Begin the session
|
||||
_sampling_thread.reset(new boost::thread(
|
||||
&SigSession::sample_thread_proc, this, _sdi,
|
||||
@ -464,6 +482,7 @@ void SigSession::feed_in_header(const sr_dev_inst *sdi)
|
||||
uint64_t sample_rate = 0;
|
||||
unsigned int logic_probe_count = 0;
|
||||
unsigned int dso_probe_count = 0;
|
||||
unsigned int dso_channel_count = 0;
|
||||
unsigned int analog_probe_count = 0;
|
||||
|
||||
// Detect what data types we will receive
|
||||
@ -499,20 +518,35 @@ void SigSession::feed_in_header(const sr_dev_inst *sdi)
|
||||
sample_rate = g_variant_get_uint64(gvar);
|
||||
g_variant_unref(gvar);
|
||||
|
||||
ret = sr_config_get(sdi->driver, SR_CONF_LIMIT_SAMPLES,
|
||||
&gvar, sdi);
|
||||
if (ret != SR_OK) {
|
||||
qDebug("Failed to get total samples");
|
||||
return;
|
||||
}
|
||||
if (g_variant_get_uint64(gvar) != 0)
|
||||
_total_sample_len = g_variant_get_uint64(gvar);
|
||||
g_variant_unref(gvar);
|
||||
// ret = sr_config_get(sdi->driver, SR_CONF_LIMIT_SAMPLES,
|
||||
// &gvar, sdi);
|
||||
// if (ret != SR_OK) {
|
||||
// qDebug("Failed to get total samples");
|
||||
// return;
|
||||
// }
|
||||
// if (g_variant_get_uint64(gvar) != 0)
|
||||
// _total_sample_len = g_variant_get_uint64(gvar);
|
||||
// g_variant_unref(gvar);
|
||||
|
||||
if (sample_rate != _last_sample_rate) {
|
||||
_last_sample_rate = sample_rate;
|
||||
sample_rate_changed(sample_rate);
|
||||
}
|
||||
ret = sr_config_get(sdi->driver, SR_CONF_EN_CH0,
|
||||
&gvar, sdi);
|
||||
if (ret != SR_OK) {
|
||||
qDebug("Failed to get ENABLE of DSO channel 0\n");
|
||||
return;
|
||||
}
|
||||
dso_channel_count += g_variant_get_boolean(gvar);
|
||||
ret = sr_config_get(sdi->driver, SR_CONF_EN_CH1,
|
||||
&gvar, sdi);
|
||||
if (ret != SR_OK) {
|
||||
qDebug("Failed to get ENABLE of DSO channel 1\n");
|
||||
return;
|
||||
}
|
||||
dso_channel_count += g_variant_get_boolean(gvar);
|
||||
|
||||
|
||||
// Create data containers for the coming data snapshots
|
||||
{
|
||||
@ -528,7 +562,7 @@ void SigSession::feed_in_header(const sr_dev_inst *sdi)
|
||||
}
|
||||
|
||||
if (dso_probe_count != 0) {
|
||||
_dso_data.reset(new data::Dso(dso_probe_count, sample_rate));
|
||||
_dso_data.reset(new data::Dso(dso_channel_count, sample_rate));
|
||||
assert(_dso_data);
|
||||
}
|
||||
|
||||
@ -693,7 +727,13 @@ void SigSession::init_signals(const sr_dev_inst *sdi)
|
||||
uint64_t sample_rate = 0;
|
||||
unsigned int logic_probe_count = 0;
|
||||
unsigned int dso_probe_count = 0;
|
||||
unsigned int dso_channel_count = 0;
|
||||
unsigned int analog_probe_count = 0;
|
||||
uint64_t vdiv;
|
||||
uint64_t timebase;
|
||||
bool coupling;
|
||||
bool active;
|
||||
int ret;
|
||||
|
||||
// Detect what data types we will receive
|
||||
for (const GSList *l = sdi->probes; l; l = l->next) {
|
||||
@ -719,21 +759,34 @@ void SigSession::init_signals(const sr_dev_inst *sdi)
|
||||
// Read out the sample rate
|
||||
assert(sdi->driver);
|
||||
|
||||
const int ret = sr_config_get(sdi->driver, SR_CONF_SAMPLERATE,
|
||||
ret = sr_config_get(sdi->driver, SR_CONF_SAMPLERATE,
|
||||
&gvar, sdi);
|
||||
if (ret != SR_OK) {
|
||||
qDebug("Failed to get samplerate\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sample_rate = g_variant_get_uint64(gvar);
|
||||
g_variant_unref(gvar);
|
||||
|
||||
if (sample_rate != _last_sample_rate) {
|
||||
_last_sample_rate = sample_rate;
|
||||
sample_rate_changed(sample_rate);
|
||||
}
|
||||
|
||||
ret = sr_config_get(sdi->driver, SR_CONF_EN_CH0,
|
||||
&gvar, sdi);
|
||||
if (ret != SR_OK) {
|
||||
qDebug("Failed to get ENABLE of DSO channel 0\n");
|
||||
return;
|
||||
}
|
||||
dso_channel_count += g_variant_get_boolean(gvar);
|
||||
ret = sr_config_get(sdi->driver, SR_CONF_EN_CH1,
|
||||
&gvar, sdi);
|
||||
if (ret != SR_OK) {
|
||||
qDebug("Failed to get ENABLE of DSO channel 1\n");
|
||||
return;
|
||||
}
|
||||
dso_channel_count += g_variant_get_boolean(gvar);
|
||||
|
||||
// Create data containers for the coming data snapshots
|
||||
{
|
||||
if (logic_probe_count != 0) {
|
||||
@ -747,7 +800,7 @@ void SigSession::init_signals(const sr_dev_inst *sdi)
|
||||
}
|
||||
|
||||
if (dso_probe_count != 0) {
|
||||
_dso_data.reset(new data::Dso(dso_probe_count, sample_rate));
|
||||
_dso_data.reset(new data::Dso(dso_channel_count, sample_rate));
|
||||
assert(_dso_data);
|
||||
}
|
||||
|
||||
@ -776,9 +829,68 @@ void SigSession::init_signals(const sr_dev_inst *sdi)
|
||||
break;
|
||||
|
||||
case SR_PROBE_DSO:
|
||||
if (probe->index == 0) {
|
||||
ret = sr_config_get(sdi->driver, SR_CONF_VDIV0,
|
||||
&gvar, sdi);
|
||||
if (ret != SR_OK) {
|
||||
qDebug("Failed to get VDIV of channel 0\n");
|
||||
return;
|
||||
}
|
||||
vdiv = g_variant_get_uint64(gvar);
|
||||
ret = sr_config_get(sdi->driver, SR_CONF_TIMEBASE,
|
||||
&gvar, sdi);
|
||||
if (ret != SR_OK) {
|
||||
qDebug("Failed to get TIMEBASE\n");
|
||||
return;
|
||||
}
|
||||
timebase = g_variant_get_uint64(gvar);
|
||||
ret = sr_config_get(sdi->driver, SR_CONF_COUPLING0,
|
||||
&gvar, sdi);
|
||||
if (ret != SR_OK) {
|
||||
qDebug("Failed to get AC COUPLING of channel 0\n");
|
||||
return;
|
||||
}
|
||||
coupling = g_variant_get_boolean(gvar);
|
||||
ret = sr_config_get(sdi->driver, SR_CONF_EN_CH0,
|
||||
&gvar, sdi);
|
||||
if (ret != SR_OK) {
|
||||
qDebug("Failed to get ENABLE of channel 0\n");
|
||||
return;
|
||||
}
|
||||
active = g_variant_get_boolean(gvar);
|
||||
} else if (probe->index == 1) {
|
||||
ret = sr_config_get(sdi->driver, SR_CONF_VDIV1,
|
||||
&gvar, sdi);
|
||||
if (ret != SR_OK) {
|
||||
qDebug("Failed to get VDIV of channel 1\n");
|
||||
return;
|
||||
}
|
||||
vdiv = g_variant_get_uint64(gvar);
|
||||
ret = sr_config_get(sdi->driver, SR_CONF_TIMEBASE,
|
||||
&gvar, sdi);
|
||||
if (ret != SR_OK) {
|
||||
qDebug("Failed to get TIMEBASE\n");
|
||||
return;
|
||||
}
|
||||
timebase = g_variant_get_uint64(gvar);
|
||||
ret = sr_config_get(sdi->driver, SR_CONF_COUPLING1,
|
||||
&gvar, sdi);
|
||||
if (ret != SR_OK) {
|
||||
qDebug("Failed to get AC COUPLING of channel 1\n");
|
||||
return;
|
||||
}
|
||||
coupling = g_variant_get_boolean(gvar);
|
||||
ret = sr_config_get(sdi->driver, SR_CONF_EN_CH1,
|
||||
&gvar, sdi);
|
||||
if (ret != SR_OK) {
|
||||
qDebug("Failed to get ENABLE of channel 1\n");
|
||||
return;
|
||||
}
|
||||
active = g_variant_get_boolean(gvar);
|
||||
}
|
||||
signal = boost::shared_ptr<view::Signal>(
|
||||
new view::DsoSignal(probe->name,
|
||||
_dso_data, probe->index, _signals.size()));
|
||||
_dso_data, probe->index, _signals.size(), vdiv, timebase, coupling, active));
|
||||
break;
|
||||
|
||||
case SR_PROBE_ANALOG:
|
||||
@ -793,6 +905,7 @@ void SigSession::init_signals(const sr_dev_inst *sdi)
|
||||
signals_changed();
|
||||
data_updated();
|
||||
}
|
||||
g_variant_unref(gvar);
|
||||
}
|
||||
|
||||
void SigSession::update_signals(const sr_dev_inst *sdi)
|
||||
@ -801,6 +914,12 @@ void SigSession::update_signals(const sr_dev_inst *sdi)
|
||||
QMap<int, bool> probes_en_table;
|
||||
QMap<int, bool> signals_en_table;
|
||||
int index = 0;
|
||||
GVariant *gvar;
|
||||
uint64_t vdiv;
|
||||
uint64_t timebase;
|
||||
bool coupling;
|
||||
bool active;
|
||||
int ret;
|
||||
|
||||
std::vector< boost::shared_ptr<view::Signal> >::iterator i = _signals.begin();
|
||||
while (i != _signals.end()) {
|
||||
@ -832,9 +951,68 @@ void SigSession::update_signals(const sr_dev_inst *sdi)
|
||||
break;
|
||||
|
||||
case SR_PROBE_DSO:
|
||||
if (probe->index == 0) {
|
||||
ret = sr_config_get(sdi->driver, SR_CONF_VDIV0,
|
||||
&gvar, sdi);
|
||||
if (ret != SR_OK) {
|
||||
qDebug("Failed to get VDIV of channel 0\n");
|
||||
return;
|
||||
}
|
||||
vdiv = g_variant_get_uint64(gvar);
|
||||
ret = sr_config_get(sdi->driver, SR_CONF_TIMEBASE,
|
||||
&gvar, sdi);
|
||||
if (ret != SR_OK) {
|
||||
qDebug("Failed to get TIMEBASE\n");
|
||||
return;
|
||||
}
|
||||
timebase = g_variant_get_uint64(gvar);
|
||||
ret = sr_config_get(sdi->driver, SR_CONF_COUPLING0,
|
||||
&gvar, sdi);
|
||||
if (ret != SR_OK) {
|
||||
qDebug("Failed to get AC COUPLING of channel 0\n");
|
||||
return;
|
||||
}
|
||||
coupling = g_variant_get_boolean(gvar);
|
||||
ret = sr_config_get(sdi->driver, SR_CONF_EN_CH0,
|
||||
&gvar, sdi);
|
||||
if (ret != SR_OK) {
|
||||
qDebug("Failed to get ENABLE of channel 0\n");
|
||||
return;
|
||||
}
|
||||
active = g_variant_get_boolean(gvar);
|
||||
} else if (probe->index == 1) {
|
||||
ret = sr_config_get(sdi->driver, SR_CONF_VDIV1,
|
||||
&gvar, sdi);
|
||||
if (ret != SR_OK) {
|
||||
qDebug("Failed to get VDIV of channel 1\n");
|
||||
return;
|
||||
}
|
||||
vdiv = g_variant_get_uint64(gvar);
|
||||
ret = sr_config_get(sdi->driver, SR_CONF_TIMEBASE,
|
||||
&gvar, sdi);
|
||||
if (ret != SR_OK) {
|
||||
qDebug("Failed to get TIMEBASE\n");
|
||||
return;
|
||||
}
|
||||
timebase = g_variant_get_uint64(gvar);
|
||||
ret = sr_config_get(sdi->driver, SR_CONF_COUPLING1,
|
||||
&gvar, sdi);
|
||||
if (ret != SR_OK) {
|
||||
qDebug("Failed to get AC COUPLING of channel 1\n");
|
||||
return;
|
||||
}
|
||||
coupling = g_variant_get_boolean(gvar);
|
||||
ret = sr_config_get(sdi->driver, SR_CONF_EN_CH1,
|
||||
&gvar, sdi);
|
||||
if (ret != SR_OK) {
|
||||
qDebug("Failed to get ENABLE of channel 1\n");
|
||||
return;
|
||||
}
|
||||
active = g_variant_get_boolean(gvar);
|
||||
}
|
||||
signal = boost::shared_ptr<view::Signal>(
|
||||
new view::DsoSignal(probe->name,
|
||||
_dso_data, probe->index, _signals.size()));
|
||||
_dso_data, probe->index, _signals.size(), vdiv, timebase, coupling, active));
|
||||
break;
|
||||
|
||||
case SR_PROBE_ANALOG:
|
||||
@ -1245,4 +1423,92 @@ void SigSession::set_adv_trigger(bool adv_trigger)
|
||||
_adv_trigger = adv_trigger;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* oscilloscope control
|
||||
*/
|
||||
void SigSession::start_dso_ctrl_proc(boost::function<void (const QString)> error_handler)
|
||||
{
|
||||
|
||||
// Begin the dso control thread
|
||||
_dso_ctrl_thread.reset(new boost::thread(
|
||||
&SigSession::dso_ctrl_proc, this, error_handler));
|
||||
|
||||
}
|
||||
|
||||
void SigSession::stop_dso_ctrl_proc()
|
||||
{
|
||||
|
||||
if (_dso_ctrl_thread.get()) {
|
||||
_dso_ctrl_thread->interrupt();
|
||||
_dso_ctrl_thread->join();
|
||||
}
|
||||
_dso_ctrl_thread.reset();
|
||||
}
|
||||
|
||||
int SigSession::set_dso_ctrl(int key)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (key== SR_CONF_TIMEBASE) {
|
||||
uint64_t timebase = _signals.at(0)->get_hDialValue();
|
||||
ret = sr_config_set(_sdi, key, g_variant_new_uint64(timebase));
|
||||
} else if (key == SR_CONF_VDIV0) {
|
||||
uint64_t vdiv = _signals.at(0)->get_vDialValue();
|
||||
ret = sr_config_set(_sdi, key, g_variant_new_uint64(vdiv));
|
||||
} else if (key == SR_CONF_VDIV1) {
|
||||
uint64_t vdiv = _signals.at(1)->get_vDialValue();
|
||||
ret = sr_config_set(_sdi, key, g_variant_new_uint64(vdiv));
|
||||
} else if (key == SR_CONF_COUPLING0) {
|
||||
bool acdc = _signals.at(0)->get_acCoupling();
|
||||
ret = sr_config_set(_sdi, key, g_variant_new_boolean(acdc));
|
||||
} else if (key == SR_CONF_COUPLING1) {
|
||||
bool acdc = _signals.at(1)->get_acCoupling();
|
||||
ret = sr_config_set(_sdi, key, g_variant_new_boolean(acdc));
|
||||
} else if (key == SR_CONF_EN_CH0) {
|
||||
bool enable = _signals.at(0)->get_active();
|
||||
ret = sr_config_set(_sdi, key, g_variant_new_boolean(enable));
|
||||
dso_ch_changed(get_dso_ch_num());
|
||||
} else if (key == SR_CONF_EN_CH1) {
|
||||
bool enable = _signals.at(1)->get_active();
|
||||
ret = sr_config_set(_sdi, key, g_variant_new_boolean(enable));
|
||||
dso_ch_changed(get_dso_ch_num());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint16_t SigSession::get_dso_ch_num()
|
||||
{
|
||||
uint16_t num_channels = 0;
|
||||
BOOST_FOREACH(const shared_ptr<view::Signal> s, _signals)
|
||||
{
|
||||
assert(s);
|
||||
if (s->get_active()) {
|
||||
num_channels++;
|
||||
}
|
||||
}
|
||||
return num_channels;
|
||||
}
|
||||
|
||||
void SigSession::dso_ctrl_proc(boost::function<void (const QString)> error_handler)
|
||||
{
|
||||
(void)error_handler;
|
||||
try {
|
||||
while(_session) {
|
||||
if (!_sdi) {
|
||||
// do nothing
|
||||
} else if (strcmp(_sdi->driver->name, "Demo") == 0) {
|
||||
|
||||
} else if (strcmp(_sdi->driver->name, "DSLogic") == 0) {
|
||||
|
||||
}
|
||||
boost::this_thread::sleep(boost::posix_time::millisec(100));
|
||||
}
|
||||
} catch(...) {
|
||||
qDebug("Interrupt exception for oscilloscope control thread was thrown.");
|
||||
}
|
||||
qDebug("Oscilloscope control thread exit!");
|
||||
}
|
||||
|
||||
} // namespace pv
|
||||
|
@ -157,38 +157,41 @@ public:
|
||||
|
||||
void set_adv_trigger(bool adv_trigger);
|
||||
|
||||
void start_dso_ctrl_proc(boost::function<void (const QString)> error_handler);
|
||||
void stop_dso_ctrl_proc();
|
||||
int set_dso_ctrl(int key);
|
||||
uint16_t get_dso_ch_num();
|
||||
|
||||
private:
|
||||
void set_capture_state(capture_state state);
|
||||
|
||||
private:
|
||||
// thread for sample/load
|
||||
void load_thread_proc(const std::string name,
|
||||
boost::function<void (const QString)> error_handler);
|
||||
|
||||
void sample_thread_proc(struct sr_dev_inst *sdi,
|
||||
uint64_t record_length,
|
||||
boost::function<void (const QString)> error_handler);
|
||||
|
||||
// data feed
|
||||
void feed_in_header(const sr_dev_inst *sdi);
|
||||
|
||||
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_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);
|
||||
|
||||
static void data_feed_in_proc(const struct sr_dev_inst *sdi,
|
||||
const struct sr_datafeed_packet *packet, void *cb_data);
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
void dso_ctrl_proc(boost::function<void (const QString)> error_handler);
|
||||
|
||||
private:
|
||||
DeviceManager &_device_manager;
|
||||
|
||||
@ -232,6 +235,11 @@ private:
|
||||
|
||||
bool _adv_trigger;
|
||||
|
||||
bool _vDial_changed;
|
||||
bool _hDial_changed;
|
||||
uint16_t _dso_ctrl_channel;
|
||||
std::auto_ptr<boost::thread> _dso_ctrl_thread;
|
||||
|
||||
signals:
|
||||
void capture_state_changed(int state);
|
||||
|
||||
@ -250,6 +258,8 @@ signals:
|
||||
|
||||
void receive_trigger(quint64 trigger_pos);
|
||||
|
||||
void dso_ch_changed(uint16_t num);
|
||||
|
||||
public slots:
|
||||
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#include <QAction>
|
||||
#include <QDebug>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "devicebar.h"
|
||||
|
||||
@ -123,11 +124,11 @@ void DeviceBar::on_configure()
|
||||
pv::dialogs::DeviceOptions dlg(this, sdi);
|
||||
ret = dlg.exec();
|
||||
if (ret == QDialog::Accepted) {
|
||||
//if (dlg.exec()) {
|
||||
if (dev_mode != sdi->mode)
|
||||
device_selected();
|
||||
else
|
||||
device_updated();
|
||||
if (dev_mode != sdi->mode) {
|
||||
device_selected();
|
||||
} else {
|
||||
device_updated();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,6 @@ public:
|
||||
|
||||
signals:
|
||||
void device_selected();
|
||||
|
||||
void device_updated();
|
||||
|
||||
private slots:
|
||||
|
@ -165,12 +165,41 @@ uint64_t SamplingBar::get_record_length() const
|
||||
return _record_length_selector.itemData(index).value<uint64_t>();
|
||||
}
|
||||
|
||||
void SamplingBar::set_record_length(uint64_t length)
|
||||
{
|
||||
for (int i = 0; i < _record_length_selector.count(); i++) {
|
||||
if (length == _record_length_selector.itemData(
|
||||
i).value<uint64_t>()) {
|
||||
_record_length_selector.setCurrentIndex(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SamplingBar::set_sampling(bool sampling)
|
||||
{
|
||||
_run_stop_button.setIcon(sampling ? _icon_stop : _icon_start);
|
||||
//_run_stop_button.setText(sampling ? " Stop" : "Start");
|
||||
}
|
||||
|
||||
void SamplingBar::set_sample_rate(uint64_t sample_rate)
|
||||
{
|
||||
for (int i = 0; i < _sample_rate_list.count(); i++) {
|
||||
if (sample_rate == _sample_rate_list.itemData(
|
||||
i).value<uint64_t>()) {
|
||||
_sample_rate_list.setCurrentIndex(i);
|
||||
// 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;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SamplingBar::update_sample_rate_selector()
|
||||
{
|
||||
GVariant *gvar_dict, *gvar_list;
|
||||
@ -280,7 +309,7 @@ void SamplingBar::commit_sample_rate()
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(_sdi->driver->name, "DSLogic") == 0) {
|
||||
if (strcmp(_sdi->driver->name, "DSLogic") == 0 && _sdi->mode != DSO) {
|
||||
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)) ||
|
||||
|
@ -54,9 +54,11 @@ public:
|
||||
SamplingBar(QWidget *parent);
|
||||
|
||||
uint64_t get_record_length() const;
|
||||
void set_record_length(uint64_t length);
|
||||
|
||||
void set_sampling(bool sampling);
|
||||
void update_sample_rate_selector();
|
||||
void set_sample_rate(uint64_t sample_rate);
|
||||
|
||||
void set_device(struct sr_dev_inst *sdi);
|
||||
|
||||
|
110
DSLogic-gui/pv/view/dsldial.cpp
Normal file
110
DSLogic-gui/pv/view/dsldial.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
#include "dsldial.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
namespace pv {
|
||||
namespace view {
|
||||
|
||||
dslDial::dslDial(quint64 div, quint64 step,
|
||||
QVector<quint64> value, QVector<QString> unit)
|
||||
{
|
||||
assert(div > 0);
|
||||
assert(step > 0);
|
||||
assert((quint64)value.count() == div);
|
||||
assert(unit.count() > 0);
|
||||
|
||||
_div = div;
|
||||
_step = step;
|
||||
_value = value;
|
||||
_unit = unit;
|
||||
_sel = 0;
|
||||
}
|
||||
|
||||
dslDial::~dslDial()
|
||||
{
|
||||
}
|
||||
|
||||
void dslDial::paint(QPainter &p, QRectF dialRect, QColor dialColor)
|
||||
{
|
||||
p.setRenderHint(QPainter::Antialiasing, true);
|
||||
p.setPen(dialColor);
|
||||
p.setBrush(dialColor);
|
||||
|
||||
int dialStartAngle = 225 * 16;
|
||||
int dialSpanAngle = -270 * 16;
|
||||
|
||||
// draw dial arc
|
||||
p.drawArc(dialRect, dialStartAngle, dialSpanAngle);
|
||||
// draw ticks
|
||||
p.save();
|
||||
p.translate(dialRect.center());
|
||||
p.rotate(45);
|
||||
for (quint64 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++) {
|
||||
p.drawLine(0, dialRect.width()/2+3, 0, dialRect.width()/2+5);
|
||||
p.rotate(54.0/(_div-1));
|
||||
}
|
||||
}
|
||||
// draw pointer
|
||||
p.rotate(90+270.0/(_div-1)*_sel);
|
||||
p.drawEllipse(-3, -3, 6, 6);
|
||||
p.drawLine(3, 0, 0, dialRect.width()/2-3);
|
||||
p.drawLine(-3, 0, 0, dialRect.width()/2-3);
|
||||
p.restore();
|
||||
// draw value
|
||||
quint64 displayValue = _value[_sel];
|
||||
quint64 displayIndex = 0;
|
||||
while(displayValue / _step >= 1) {
|
||||
displayValue = displayValue / _step;
|
||||
displayIndex++;
|
||||
}
|
||||
QString pText = QString::number(displayValue) + _unit[displayIndex] + "/div";
|
||||
QFontMetrics fm(p.font());
|
||||
p.drawText(QRectF(dialRect.left(), dialRect.bottom()-dialRect.width()*0.3+fm.height()*0.5, dialRect.width(), fm.height()), Qt::AlignCenter, pText);
|
||||
|
||||
}
|
||||
|
||||
void dslDial::set_sel(quint64 sel)
|
||||
{
|
||||
assert(sel < _div);
|
||||
|
||||
_sel = sel;
|
||||
}
|
||||
|
||||
quint64 dslDial::get_sel()
|
||||
{
|
||||
return _sel;
|
||||
}
|
||||
|
||||
bool dslDial::isMin()
|
||||
{
|
||||
if(_sel == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool dslDial::isMax()
|
||||
{
|
||||
if(_sel == _div - 1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
quint64 dslDial::get_value()
|
||||
{
|
||||
return _value[_sel];
|
||||
}
|
||||
|
||||
bool dslDial::set_value(quint64 value)
|
||||
{
|
||||
assert(_value.contains(value));
|
||||
_sel = _value.indexOf(value, 0);
|
||||
}
|
||||
|
||||
} // namespace view
|
||||
} // namespace pv
|
48
DSLogic-gui/pv/view/dsldial.h
Normal file
48
DSLogic-gui/pv/view/dsldial.h
Normal file
@ -0,0 +1,48 @@
|
||||
#ifndef DSLOGIC_PV_VIEW_DSLDIAL_H
|
||||
#define DSLOGIC_PV_VIEW_DSLDIAL_H
|
||||
|
||||
#include <QRect>
|
||||
#include <QPainter>
|
||||
|
||||
namespace pv {
|
||||
namespace view {
|
||||
|
||||
class dslDial
|
||||
{
|
||||
public:
|
||||
dslDial(quint64 div, quint64 step,
|
||||
QVector<quint64> value, QVector<QString> unit);
|
||||
virtual ~dslDial();
|
||||
|
||||
public:
|
||||
/**
|
||||
* Paints the dial with a QPainter
|
||||
* @param p the QPainter to paint into.
|
||||
* @param dialRect the rectangle to draw the dial at.
|
||||
**/
|
||||
void paint(QPainter &p, QRectF dialRect, QColor dialColor);
|
||||
|
||||
// set/get current select
|
||||
void set_sel(quint64 sel);
|
||||
quint64 get_sel();
|
||||
|
||||
// boundary detection
|
||||
bool isMin();
|
||||
bool isMax();
|
||||
|
||||
// get current value
|
||||
quint64 get_value();
|
||||
bool set_value(quint64 value);
|
||||
|
||||
private:
|
||||
quint64 _div;
|
||||
quint64 _step;
|
||||
QVector<quint64> _value;
|
||||
QVector<QString> _unit;
|
||||
quint64 _sel;
|
||||
};
|
||||
|
||||
} // namespace view
|
||||
} // namespace pv
|
||||
|
||||
#endif // DSLOGIC_PV_VIEW_DSLDIAL_H
|
@ -35,21 +35,26 @@ 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
|
||||
QColor(238, 178, 17, 200), // dsYellow
|
||||
QColor(0, 153, 37, 200), // dsGreen
|
||||
QColor(213, 15, 37, 200), // dsRed
|
||||
QColor(17, 133, 209, 200) // dsBlue
|
||||
|
||||
};
|
||||
|
||||
const float DsoSignal::EnvelopeThreshold = 256.0f;
|
||||
|
||||
DsoSignal::DsoSignal(QString name, boost::shared_ptr<data::Dso> data,
|
||||
int probe_index, int order) :
|
||||
int probe_index, int order, uint64_t vdiv, uint64_t timebase, bool coupling, bool active) :
|
||||
Signal(name, probe_index, DS_DSO, order),
|
||||
_data(data)
|
||||
{
|
||||
_colour = SignalColours[probe_index % countof(SignalColours)];
|
||||
_scale = _signalHeight * 1.0f / 256;
|
||||
_scale = _windowHeight * 1.0f / 256;
|
||||
_vDial->set_value(vdiv);
|
||||
_hDial->set_value(timebase);
|
||||
_acCoupling = coupling;
|
||||
_active = active;
|
||||
}
|
||||
|
||||
DsoSignal::~DsoSignal()
|
||||
@ -76,28 +81,27 @@ void DsoSignal::set_scale(float scale)
|
||||
}
|
||||
|
||||
void DsoSignal::paint(QPainter &p, int y, int left, int right, double scale,
|
||||
double offset)
|
||||
double offset)
|
||||
{
|
||||
assert(scale > 0);
|
||||
assert(_data);
|
||||
assert(right >= left);
|
||||
|
||||
//paint_axis(p, y, left, right);
|
||||
|
||||
const deque< boost::shared_ptr<pv::data::DsoSnapshot> > &snapshots =
|
||||
_data->get_snapshots();
|
||||
if (snapshots.empty())
|
||||
return;
|
||||
|
||||
_scale = _signalHeight * 1.0f / 256;
|
||||
_scale = _windowHeight * 1.0f / 256;
|
||||
const boost::shared_ptr<pv::data::DsoSnapshot> &snapshot =
|
||||
snapshots.front();
|
||||
|
||||
if ((unsigned int)get_index() >= snapshot->get_channel_num())
|
||||
const uint16_t number_channels = snapshot->get_channel_num();
|
||||
if ((unsigned int)get_index() >= number_channels)
|
||||
return;
|
||||
|
||||
const double pixels_offset = offset / scale;
|
||||
const double samplerate = _data->get_samplerate();
|
||||
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;
|
||||
@ -112,7 +116,7 @@ void DsoSignal::paint(QPainter &p, int y, int left, int right, double scale,
|
||||
if (samples_per_pixel < EnvelopeThreshold)
|
||||
paint_trace(p, snapshot, y, left,
|
||||
start_sample, end_sample,
|
||||
pixels_offset, samples_per_pixel);
|
||||
pixels_offset, samples_per_pixel, number_channels);
|
||||
else
|
||||
paint_envelope(p, snapshot, y, left,
|
||||
start_sample, end_sample,
|
||||
@ -121,13 +125,13 @@ void DsoSignal::paint(QPainter &p, int y, int left, int right, double scale,
|
||||
|
||||
void DsoSignal::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)
|
||||
int y, int left, const int64_t start, const int64_t end,
|
||||
const double pixels_offset, const double samples_per_pixel, uint64_t num_channels)
|
||||
{
|
||||
const int64_t sample_count = end - start;
|
||||
|
||||
if (sample_count > 0) {
|
||||
const uint16_t *const samples = snapshot->get_samples(start, end);
|
||||
const uint8_t *const samples = snapshot->get_samples(start, end, get_index());
|
||||
assert(samples);
|
||||
|
||||
p.setPen(_colour);
|
||||
@ -136,11 +140,11 @@ void DsoSignal::paint_trace(QPainter &p,
|
||||
QPointF *points = new QPointF[sample_count];
|
||||
QPointF *point = points;
|
||||
|
||||
for (int64_t sample = start; sample != end; sample++) {
|
||||
for (int64_t sample = start; sample < end; sample++) {
|
||||
const float x = (sample / samples_per_pixel - pixels_offset) + left;
|
||||
uint16_t offset = samples[sample - start];
|
||||
uint8_t offset = samples[(sample - start)*num_channels];
|
||||
*point++ = QPointF(x,
|
||||
y - ((get_index() == 0) ? offset & 0x00ff : offset >> 8) * _scale);
|
||||
y - offset * _scale);
|
||||
}
|
||||
|
||||
p.drawPolyline(points, point - points);
|
||||
|
@ -47,7 +47,8 @@ private:
|
||||
|
||||
public:
|
||||
DsoSignal(QString name,
|
||||
boost::shared_ptr<pv::data::Dso> data, int probe_index, int order);
|
||||
boost::shared_ptr<pv::data::Dso> data, int probe_index, int order,
|
||||
uint64_t vdiv, uint64_t timebase, bool coupling, bool active);
|
||||
|
||||
virtual ~DsoSignal();
|
||||
|
||||
@ -63,8 +64,8 @@ public:
|
||||
* @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);
|
||||
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;
|
||||
|
||||
@ -83,7 +84,8 @@ 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);
|
||||
const double pixels_offset, const double samples_per_pixel,
|
||||
uint64_t num_channels);
|
||||
|
||||
void paint_envelope(QPainter &p,
|
||||
const boost::shared_ptr<pv::data::DsoSnapshot> &snapshot,
|
||||
|
@ -50,7 +50,7 @@ GroupSignal::GroupSignal(QString name, boost::shared_ptr<data::Group> data,
|
||||
_data(data)
|
||||
{
|
||||
_colour = SignalColours[probe_index_list.front() % countof(SignalColours)];
|
||||
_scale = _signalHeight * 1.0f / std::pow(2.0, static_cast<double>(probe_index_list.size()));
|
||||
_scale = _signalHeight * 1.0f / pow(2, probe_index_list.size());
|
||||
}
|
||||
|
||||
GroupSignal::~GroupSignal()
|
||||
@ -77,13 +77,13 @@ void GroupSignal::set_scale(float scale)
|
||||
}
|
||||
|
||||
void GroupSignal::paint(QPainter &p, int y, int left, int right, double scale,
|
||||
double offset)
|
||||
double offset)
|
||||
{
|
||||
assert(scale > 0);
|
||||
assert(_data);
|
||||
assert(right >= left);
|
||||
|
||||
_scale = _signalHeight * 1.0f / std::pow(2.0, static_cast<int>(_index_list.size()));
|
||||
_scale = _signalHeight * 1.0f / pow(2, _index_list.size());
|
||||
paint_axis(p, y, left, right);
|
||||
|
||||
const deque< boost::shared_ptr<pv::data::GroupSnapshot> > &snapshots =
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <QPainter>
|
||||
#include <QRect>
|
||||
#include <QStyleOption>
|
||||
#include <QMessageBox>
|
||||
|
||||
using namespace boost;
|
||||
using namespace std;
|
||||
@ -46,14 +47,6 @@ using namespace std;
|
||||
namespace pv {
|
||||
namespace view {
|
||||
|
||||
const int Header::COLOR = 1;
|
||||
const int Header::NAME = 2;
|
||||
const int Header::POSTRIG = 3;
|
||||
const int Header::HIGTRIG = 4;
|
||||
const int Header::NEGTRIG = 5;
|
||||
const int Header::LOWTRIG = 6;
|
||||
const int Header::LABEL = 7;
|
||||
|
||||
Header::Header(View &parent) :
|
||||
QWidget(&parent),
|
||||
_view(parent),
|
||||
@ -90,7 +83,7 @@ int Header::get_nameEditWidth()
|
||||
return 0;
|
||||
}
|
||||
|
||||
boost::shared_ptr<pv::view::Signal> Header::get_mouse_over_signal(
|
||||
boost::shared_ptr<pv::view::Signal> Header::get_mSig(
|
||||
int &action,
|
||||
const QPoint &pt)
|
||||
{
|
||||
@ -185,17 +178,18 @@ void Header::mousePressEvent(QMouseEvent *event)
|
||||
make_pair(s, s->get_v_offset()));
|
||||
|
||||
// Select the signal if it has been clicked
|
||||
const boost::shared_ptr<Signal> mouse_over_signal =
|
||||
get_mouse_over_signal(action, event->pos());
|
||||
if (action == COLOR && mouse_over_signal) {
|
||||
const boost::shared_ptr<Signal> mSig =
|
||||
get_mSig(action, event->pos());
|
||||
if (action == Signal::COLOR && mSig) {
|
||||
_colorFlag = true;
|
||||
} else if (action == NAME && mouse_over_signal) {
|
||||
} else if (action == Signal::NAME && mSig) {
|
||||
_nameFlag = true;
|
||||
} else if (action == LABEL && mouse_over_signal) {
|
||||
if (mouse_over_signal->selected())
|
||||
mouse_over_signal->select(false);
|
||||
} else if (action == Signal::LABEL && mSig) {
|
||||
if (mSig->selected())
|
||||
mSig->select(false);
|
||||
else {
|
||||
mouse_over_signal->select(true);
|
||||
if (mSig->get_type() != Signal::DS_DSO)
|
||||
mSig->select(true);
|
||||
|
||||
if (~QApplication::keyboardModifiers() &
|
||||
Qt::ControlModifier)
|
||||
@ -204,37 +198,91 @@ void Header::mousePressEvent(QMouseEvent *event)
|
||||
// Add the signal to the drag list
|
||||
if (event->button() & Qt::LeftButton)
|
||||
_drag_sigs.push_back(
|
||||
make_pair(mouse_over_signal,
|
||||
mouse_over_signal->get_v_offset()));
|
||||
make_pair(mSig,
|
||||
(mSig->get_type() == Signal::DS_DSO) ? mSig->get_zeroPos() : mSig->get_v_offset()));
|
||||
}
|
||||
mouse_over_signal->set_old_v_offset(mouse_over_signal->get_v_offset());
|
||||
} else if (action == POSTRIG && mouse_over_signal) {
|
||||
if (mouse_over_signal->get_trig() == POSTRIG)
|
||||
mouse_over_signal->set_trig(0);
|
||||
mSig->set_old_v_offset(mSig->get_v_offset());
|
||||
} else if (action == Signal::POSTRIG && mSig) {
|
||||
if (mSig->get_trig() == Signal::POSTRIG)
|
||||
mSig->set_trig(0);
|
||||
else
|
||||
mouse_over_signal->set_trig(POSTRIG);
|
||||
} else if (action == HIGTRIG && mouse_over_signal) {
|
||||
if (mouse_over_signal->get_trig() == HIGTRIG)
|
||||
mouse_over_signal->set_trig(0);
|
||||
mSig->set_trig(Signal::POSTRIG);
|
||||
} else if (action == Signal::HIGTRIG && mSig) {
|
||||
if (mSig->get_trig() == Signal::HIGTRIG)
|
||||
mSig->set_trig(0);
|
||||
else
|
||||
mouse_over_signal->set_trig(HIGTRIG);
|
||||
} else if (action == NEGTRIG && mouse_over_signal) {
|
||||
if (mouse_over_signal->get_trig() == NEGTRIG)
|
||||
mouse_over_signal->set_trig(0);
|
||||
mSig->set_trig(Signal::HIGTRIG);
|
||||
} else if (action == Signal::NEGTRIG && mSig) {
|
||||
if (mSig->get_trig() == Signal::NEGTRIG)
|
||||
mSig->set_trig(0);
|
||||
else
|
||||
mouse_over_signal->set_trig(NEGTRIG);
|
||||
} else if (action == LOWTRIG && mouse_over_signal) {
|
||||
if (mouse_over_signal->get_trig() == LOWTRIG)
|
||||
mouse_over_signal->set_trig(0);
|
||||
mSig->set_trig(Signal::NEGTRIG);
|
||||
} else if (action == Signal::LOWTRIG && mSig) {
|
||||
if (mSig->get_trig() == Signal::LOWTRIG)
|
||||
mSig->set_trig(0);
|
||||
else
|
||||
mouse_over_signal->set_trig(LOWTRIG);
|
||||
mSig->set_trig(Signal::LOWTRIG);
|
||||
} else if (action == Signal::EDGETRIG && mSig) {
|
||||
if (mSig->get_trig() == Signal::EDGETRIG)
|
||||
mSig->set_trig(0);
|
||||
else
|
||||
mSig->set_trig(Signal::EDGETRIG);
|
||||
} else if (action == Signal::VDIAL && mSig) {
|
||||
BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
|
||||
s->set_hDialActive(false);
|
||||
if (s != mSig) {
|
||||
s->set_vDialActive(false);
|
||||
}
|
||||
}
|
||||
mSig->set_vDialActive(!mSig->get_vDialActive());
|
||||
} else if (action == Signal::HDIAL && mSig) {
|
||||
if (mSig->get_hDialActive()) {
|
||||
BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
|
||||
s->set_vDialActive(false);
|
||||
s->set_hDialActive(false);
|
||||
}
|
||||
} else {
|
||||
BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
|
||||
s->set_vDialActive(false);
|
||||
s->set_hDialActive(true);
|
||||
}
|
||||
}
|
||||
} else if (action == Signal::CHEN && mSig) {
|
||||
int channel;
|
||||
if (mSig->get_index() == 0) {
|
||||
bool last = 1;
|
||||
channel = 0;
|
||||
BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
|
||||
if (s->get_index() != 0 && s->get_active()) {
|
||||
QMessageBox msg(this);
|
||||
msg.setText("Tips");
|
||||
msg.setInformativeText("If only one channel want, Channel0 has a higher maximum sample rate!");
|
||||
msg.setStandardButtons(QMessageBox::Ok);
|
||||
msg.setIcon(QMessageBox::Information);
|
||||
msg.exec();
|
||||
s->set_active(!s->get_active());
|
||||
last = 0;
|
||||
channel = s->get_index();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (last)
|
||||
mSig->set_active(!mSig->get_active());
|
||||
} else {
|
||||
mSig->set_active(!mSig->get_active());
|
||||
channel = mSig->get_index();
|
||||
}
|
||||
ch_changed(channel);
|
||||
} else if (action == Signal::ACDC && mSig) {
|
||||
mSig->set_acCoupling(!mSig->get_acCoupling());
|
||||
acdc_changed(mSig->get_index());
|
||||
}
|
||||
|
||||
if (~QApplication::keyboardModifiers() & Qt::ControlModifier) {
|
||||
// Unselect all other signals because the Ctrl is not
|
||||
// pressed
|
||||
BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs)
|
||||
if (s != mouse_over_signal)
|
||||
if (s != mSig)
|
||||
s->select(false);
|
||||
}
|
||||
update();
|
||||
@ -247,15 +295,15 @@ void Header::mouseReleaseEvent(QMouseEvent *event)
|
||||
|
||||
// judge for color / name / trigger / move
|
||||
int action;
|
||||
const boost::shared_ptr<Signal> mouse_over_signal =
|
||||
get_mouse_over_signal(action, event->pos());
|
||||
if (mouse_over_signal){
|
||||
if (action == COLOR && _colorFlag) {
|
||||
_context_signal = mouse_over_signal;
|
||||
const boost::shared_ptr<Signal> mSig =
|
||||
get_mSig(action, event->pos());
|
||||
if (mSig){
|
||||
if (action == Signal::COLOR && _colorFlag) {
|
||||
_context_signal = mSig;
|
||||
changeColor(event);
|
||||
_view.set_need_update(true);
|
||||
} else if (action == NAME && _nameFlag) {
|
||||
_context_signal = mouse_over_signal;
|
||||
} else if (action == Signal::NAME && _nameFlag) {
|
||||
_context_signal = mSig;
|
||||
changeName(event);
|
||||
}
|
||||
}
|
||||
@ -270,6 +318,42 @@ void Header::mouseReleaseEvent(QMouseEvent *event)
|
||||
_view.normalize_layout();
|
||||
}
|
||||
|
||||
void Header::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
assert(event);
|
||||
|
||||
if (event->orientation() == Qt::Vertical) {
|
||||
const vector< shared_ptr<Signal> > sigs(
|
||||
_view.session().get_signals());
|
||||
// Vertical scrolling
|
||||
double shift = event->delta() / 20.0;
|
||||
if (shift > 1.0) {
|
||||
BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
|
||||
if (s->get_vDialActive()) {
|
||||
if(s->go_vDialNext())
|
||||
vDial_changed(s->get_index());
|
||||
break;
|
||||
} else if (s->get_hDialActive()) {
|
||||
if(s->go_hDialNext())
|
||||
hDial_changed(0);
|
||||
}
|
||||
}
|
||||
} else if (shift < -1.0) {
|
||||
BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
|
||||
if (s->get_vDialActive()) {
|
||||
if(s->go_vDialPre())
|
||||
vDial_changed(s->get_index());
|
||||
break;
|
||||
} else if (s->get_hDialActive()) {
|
||||
if(s->go_hDialPre())
|
||||
hDial_changed(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void Header::move(QMouseEvent *event)
|
||||
{
|
||||
bool _moveValid = false;
|
||||
@ -439,24 +523,31 @@ void Header::mouseMoveEvent(QMouseEvent *event)
|
||||
i != _drag_sigs.end(); i++) {
|
||||
const boost::shared_ptr<Signal> sig((*i).first);
|
||||
if (sig) {
|
||||
const int y = (*i).second + delta;
|
||||
const int y_snap =
|
||||
((y + View::SignalSnapGridSize / 2) /
|
||||
View::SignalSnapGridSize) *
|
||||
View::SignalSnapGridSize;
|
||||
if (y_snap != sig->get_v_offset()) {
|
||||
_moveFlag = true;
|
||||
sig->set_v_offset(y_snap);
|
||||
int y = (*i).second + delta;
|
||||
if (sig->get_type() != Signal::DS_DSO) {
|
||||
const int y_snap =
|
||||
((y + View::SignalSnapGridSize / 2) /
|
||||
View::SignalSnapGridSize) *
|
||||
View::SignalSnapGridSize;
|
||||
if (y_snap != sig->get_v_offset()) {
|
||||
_moveFlag = true;
|
||||
sig->set_v_offset(y_snap);
|
||||
}
|
||||
// Ensure the signal is selected
|
||||
sig->select(true);
|
||||
} else {
|
||||
if (y < 0)
|
||||
y = 0;
|
||||
else if (y > height())
|
||||
y = height();
|
||||
sig->set_zeroPos(y);
|
||||
sig->select(false);
|
||||
signals_moved();
|
||||
}
|
||||
// Ensure the signal is selected
|
||||
sig->select(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//signals_moved();
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
@ -470,10 +561,9 @@ void Header::contextMenuEvent(QContextMenuEvent *event)
|
||||
{
|
||||
int action;
|
||||
|
||||
const boost::shared_ptr<Signal> s = get_mouse_over_signal(action, _mouse_point);
|
||||
const boost::shared_ptr<Signal> s = get_mSig(action, _mouse_point);
|
||||
|
||||
//if (!s || action != LABEL)
|
||||
if (!s || !s->selected() || action != LABEL)
|
||||
if (!s || !s->selected() || action != Signal::LABEL)
|
||||
return;
|
||||
|
||||
QMenu menu(this);
|
||||
|
@ -47,16 +47,7 @@ public:
|
||||
Header(View &parent);
|
||||
|
||||
private:
|
||||
static const int COLOR;
|
||||
static const int NAME;
|
||||
static const int POSTRIG;
|
||||
static const int HIGTRIG;
|
||||
static const int NEGTRIG;
|
||||
static const int LOWTRIG;
|
||||
static const int LABEL;
|
||||
|
||||
private:
|
||||
boost::shared_ptr<pv::view::Signal> get_mouse_over_signal(
|
||||
boost::shared_ptr<pv::view::Signal> get_mSig(
|
||||
int &action,
|
||||
const QPoint &pt);
|
||||
|
||||
@ -65,13 +56,10 @@ private:
|
||||
|
||||
private:
|
||||
void mousePressEvent(QMouseEvent * event);
|
||||
|
||||
void mouseReleaseEvent(QMouseEvent *event);
|
||||
|
||||
void mouseMoveEvent(QMouseEvent *event);
|
||||
|
||||
void leaveEvent(QEvent *event);
|
||||
|
||||
void wheelEvent(QWheelEvent *event);
|
||||
void contextMenuEvent(QContextMenuEvent *event);
|
||||
|
||||
void move(QMouseEvent *event);
|
||||
@ -93,8 +81,11 @@ private slots:
|
||||
|
||||
signals:
|
||||
void signals_moved();
|
||||
|
||||
void header_updated();
|
||||
void vDial_changed(quint16);
|
||||
void hDial_changed(quint16);
|
||||
void acdc_changed(quint16);
|
||||
void ch_changed(quint16);
|
||||
|
||||
private:
|
||||
View &_view;
|
||||
|
@ -33,26 +33,67 @@
|
||||
namespace pv {
|
||||
namespace view {
|
||||
|
||||
const int Signal::SquareWidth = 20;
|
||||
const int Signal::Margin = 5;
|
||||
|
||||
const int Signal::COLOR = 1;
|
||||
const int Signal::NAME = 2;
|
||||
const int Signal::POSTRIG = 3;
|
||||
const int Signal::HIGTRIG = 4;
|
||||
const int Signal::NEGTRIG = 5;
|
||||
const int Signal::LOWTRIG = 6;
|
||||
const int Signal::LABEL = 7;
|
||||
|
||||
const QColor Signal::dsBlue = QColor(17, 133, 209, 255);
|
||||
const QColor Signal::dsYellow = QColor(238, 178, 17, 255);
|
||||
const QColor Signal::dsRed = QColor(213, 15, 37, 255);
|
||||
const QColor Signal::dsGreen = QColor(0, 153, 37, 255);
|
||||
const QColor Signal::dsGray = QColor(0x88, 0x8A, 0x85, 100);
|
||||
const QColor Signal::dsDisable = QColor(0x88, 0x8A, 0x85, 200);
|
||||
const QColor Signal::dsActive = QColor(17, 133, 209, 255);
|
||||
const QColor Signal::dsLightBlue = QColor(17, 133, 209, 150);
|
||||
const QColor Signal::dsLightRed = QColor(213, 15, 37, 150);
|
||||
const QPen Signal::SignalAxisPen = QColor(128, 128, 128, 64);
|
||||
|
||||
const QPen Signal::SignalAxisPen(QColor(128, 128, 128, 64));
|
||||
const uint64_t Signal::vDialValue[Signal::vDialValueCount] = {
|
||||
5,
|
||||
10,
|
||||
20,
|
||||
50,
|
||||
100,
|
||||
200,
|
||||
500,
|
||||
1000,
|
||||
2000,
|
||||
5000,
|
||||
};
|
||||
const QString Signal::vDialUnit[Signal::vDialUnitCount] = {
|
||||
"mv",
|
||||
"v",
|
||||
};
|
||||
|
||||
const uint64_t Signal::hDialValue[Signal::hDialValueCount] = {
|
||||
10,
|
||||
20,
|
||||
50,
|
||||
100,
|
||||
200,
|
||||
500,
|
||||
1000,
|
||||
2000,
|
||||
5000,
|
||||
10000,
|
||||
20000,
|
||||
50000,
|
||||
100000,
|
||||
200000,
|
||||
500000,
|
||||
1000000,
|
||||
2000000,
|
||||
5000000,
|
||||
10000000,
|
||||
20000000,
|
||||
50000000,
|
||||
100000000,
|
||||
200000000,
|
||||
500000000,
|
||||
1000000000,
|
||||
};
|
||||
const QString Signal::hDialUnit[Signal::hDialUnitCount] = {
|
||||
"ns",
|
||||
"us",
|
||||
"ms",
|
||||
"s",
|
||||
};
|
||||
|
||||
Signal::Signal(QString name, int index, int type, int order) :
|
||||
_type(type),
|
||||
@ -62,9 +103,37 @@ Signal::Signal(QString name, int index, int type, int order) :
|
||||
_v_offset(0),
|
||||
_signalHeight(30),
|
||||
_selected(false),
|
||||
_trig(0)
|
||||
_trig(0),
|
||||
_vDialActive(false),
|
||||
_hDialActive(false),
|
||||
_acCoupling(false),
|
||||
_active(true),
|
||||
_windowHeight(0)
|
||||
{
|
||||
_index_list.push_back(index);
|
||||
if (_type == DS_DSO) {
|
||||
QVector<uint64_t> vValue;
|
||||
QVector<QString> vUnit;
|
||||
QVector<uint64_t> hValue;
|
||||
QVector<QString> hUnit;
|
||||
for(quint64 i = 0; i < Signal::vDialValueCount; i++)
|
||||
vValue.append(Signal::vDialValue[i]);
|
||||
for(quint64 i = 0; i < Signal::vDialUnitCount; i++)
|
||||
vUnit.append(Signal::vDialUnit[i]);
|
||||
|
||||
for(quint64 i = 0; i < Signal::hDialValueCount; i++)
|
||||
hValue.append(Signal::hDialValue[i]);
|
||||
for(quint64 i = 0; i < Signal::hDialUnitCount; i++)
|
||||
hUnit.append(Signal::hDialUnit[i]);
|
||||
|
||||
_vDial = new dslDial(vDialValueCount, vDialValueStep, vValue, vUnit);
|
||||
_hDial = new dslDial(hDialValueCount, hDialValueStep, hValue, hUnit);
|
||||
_vDial->set_sel(0);
|
||||
_hDial->set_sel(0);
|
||||
|
||||
_trig_vpos = 0;
|
||||
_trig_en = true;
|
||||
}
|
||||
}
|
||||
|
||||
Signal::Signal(QString name, std::list<int> index_list, int type, int order, int sec_index) :
|
||||
@ -76,8 +145,32 @@ Signal::Signal(QString name, std::list<int> index_list, int type, int order, int
|
||||
_v_offset(0),
|
||||
_signalHeight(30),
|
||||
_selected(false),
|
||||
_trig(0)
|
||||
_trig(0),
|
||||
_vDialActive(false),
|
||||
_hDialActive(false),
|
||||
_acCoupling(false),
|
||||
_active(true)
|
||||
{
|
||||
if (_type == DS_DSO) {
|
||||
QVector<uint64_t> vValue;
|
||||
QVector<QString> vUnit;
|
||||
QVector<uint64_t> hValue;
|
||||
QVector<QString> hUnit;
|
||||
for(quint64 i = 0; i < Signal::vDialValueCount; i++)
|
||||
vValue.append(Signal::vDialValue[i]);
|
||||
for(quint64 i = 0; i < Signal::vDialUnitCount; i++)
|
||||
vUnit.append(Signal::vDialUnit[i]);
|
||||
|
||||
for(quint64 i = 0; i < Signal::hDialValueCount; i++)
|
||||
hValue.append(Signal::hDialValue[i]);
|
||||
for(quint64 i = 0; i < Signal::hDialUnitCount; i++)
|
||||
hUnit.append(Signal::hDialUnit[i]);
|
||||
|
||||
_vDial = new dslDial(Signal::vDialValueCount, Signal::vDialValueStep, vValue, vUnit);
|
||||
_hDial = new dslDial(Signal::hDialValueCount, Signal::hDialValueStep, hValue, hUnit);
|
||||
_vDial->set_sel(0);
|
||||
_hDial->set_sel(0);
|
||||
}
|
||||
}
|
||||
|
||||
int Signal::get_type() const
|
||||
@ -104,7 +197,7 @@ int Signal::get_leftWidth() const
|
||||
|
||||
int Signal::get_rightWidth() const
|
||||
{
|
||||
return 2 * Margin + 4 * SquareWidth + 1.5 * SquareWidth;
|
||||
return 2 * Margin + SquareNum * SquareWidth + 1.5 * SquareWidth;
|
||||
}
|
||||
|
||||
int Signal::get_headerHeight() const
|
||||
@ -217,31 +310,174 @@ void Signal::set_trig(int trig)
|
||||
ds_trigger_probe_set(_index_list.front(), 'F', 'X');
|
||||
else if (trig == LOWTRIG)
|
||||
ds_trigger_probe_set(_index_list.front(), '0', 'X');
|
||||
else if (trig == EDGETRIG)
|
||||
ds_trigger_probe_set(_index_list.front(), 'C', 'X');
|
||||
}
|
||||
|
||||
bool Signal::get_vDialActive() const
|
||||
{
|
||||
return _vDialActive;
|
||||
}
|
||||
|
||||
void Signal::set_vDialActive(bool active)
|
||||
{
|
||||
_vDialActive = active;
|
||||
}
|
||||
|
||||
bool Signal::go_vDialPre()
|
||||
{
|
||||
assert(_type == DS_DSO);
|
||||
|
||||
if (!_vDial->isMin()) {
|
||||
_vDial->set_sel(_vDial->get_sel() - 1);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Signal::go_vDialNext()
|
||||
{
|
||||
assert(_type == DS_DSO);
|
||||
|
||||
if (!_vDial->isMax()) {
|
||||
_vDial->set_sel(_vDial->get_sel() + 1);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Signal::get_hDialActive() const
|
||||
{
|
||||
return _hDialActive;
|
||||
}
|
||||
|
||||
void Signal::set_hDialActive(bool active)
|
||||
{
|
||||
_hDialActive = active;
|
||||
}
|
||||
|
||||
bool Signal::go_hDialPre()
|
||||
{
|
||||
assert(_type == DS_DSO);
|
||||
|
||||
if (!_hDial->isMin()) {
|
||||
_hDial->set_sel(_hDial->get_sel() - 1);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Signal::go_hDialNext()
|
||||
{
|
||||
assert(_type == DS_DSO);
|
||||
|
||||
if (!_hDial->isMax()) {
|
||||
_hDial->set_sel(_hDial->get_sel() + 1);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t Signal::get_vDialValue() const
|
||||
{
|
||||
return _vDial->get_value();
|
||||
}
|
||||
|
||||
uint64_t Signal::get_hDialValue() const
|
||||
{
|
||||
return _hDial->get_value();
|
||||
}
|
||||
|
||||
uint16_t Signal::get_vDialSel() const
|
||||
{
|
||||
return _vDial->get_sel();
|
||||
}
|
||||
|
||||
uint16_t Signal::get_hDialSel() const
|
||||
{
|
||||
return _hDial->get_sel();
|
||||
}
|
||||
|
||||
bool Signal::get_acCoupling() const
|
||||
{
|
||||
return _acCoupling;
|
||||
}
|
||||
|
||||
void Signal::set_acCoupling(bool coupling)
|
||||
{
|
||||
_acCoupling = coupling;
|
||||
}
|
||||
|
||||
bool Signal::get_active() const
|
||||
{
|
||||
return _active;
|
||||
}
|
||||
|
||||
void Signal::set_active(bool active)
|
||||
{
|
||||
_active = active;
|
||||
}
|
||||
|
||||
int Signal::get_zeroPos() const
|
||||
{
|
||||
return _zeroPos;
|
||||
}
|
||||
|
||||
void Signal::set_zeroPos(int pos)
|
||||
{
|
||||
_zeroPos = pos;
|
||||
}
|
||||
|
||||
int Signal::get_windowHeight() const
|
||||
{
|
||||
return _windowHeight;
|
||||
}
|
||||
|
||||
void Signal::set_windowHeight(int height)
|
||||
{
|
||||
_windowHeight = height;
|
||||
}
|
||||
|
||||
int Signal::get_trig_vpos() const
|
||||
{
|
||||
return _trig_vpos;
|
||||
}
|
||||
|
||||
void Signal::set_trig_vpos(int value)
|
||||
{
|
||||
_trig_vpos = value;
|
||||
}
|
||||
|
||||
void Signal::paint_label(QPainter &p, int y, int right, bool hover, int action)
|
||||
{
|
||||
compute_text_size(p);
|
||||
|
||||
const QRectF color_rect = get_rect("color", y, right);
|
||||
const QRectF name_rect = get_rect("name", y, right);
|
||||
const QRectF posTrig_rect = get_rect("posTrig", y, right);
|
||||
const QRectF higTrig_rect = get_rect("higTrig", y, right);
|
||||
const QRectF negTrig_rect = get_rect("negTrig", y, right);
|
||||
const QRectF lowTrig_rect = get_rect("lowTrig", y, right);
|
||||
const QRectF label_rect = get_rect("label", y, right);
|
||||
const QRectF label_rect = get_rect("label", (_type == DS_DSO) ? _zeroPos : y, right);
|
||||
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
// Paint the ColorButton
|
||||
p.setPen(Qt::transparent);
|
||||
p.setBrush(_colour);
|
||||
p.setBrush(_active ? _colour : dsDisable);
|
||||
p.drawRect(color_rect);
|
||||
|
||||
// Paint the signal name
|
||||
p.setPen(Qt::black);
|
||||
p.setPen(_active ? Qt::black : dsDisable);
|
||||
p.drawText(name_rect, Qt::AlignLeft | Qt::AlignVCenter, _name);
|
||||
|
||||
// Paint the trigButton
|
||||
if (_type == DS_LOGIC) {
|
||||
if (_type == DS_LOGIC) {
|
||||
const QRectF posTrig_rect = get_rect("posTrig", y, right);
|
||||
const QRectF higTrig_rect = get_rect("higTrig", y, right);
|
||||
const QRectF negTrig_rect = get_rect("negTrig", y, right);
|
||||
const QRectF lowTrig_rect = get_rect("lowTrig", y, right);
|
||||
const QRectF edgeTrig_rect = get_rect("edgeTrig", y, right);
|
||||
|
||||
p.setPen(Qt::transparent);
|
||||
p.setBrush(((hover && action == POSTRIG) || (_trig == POSTRIG)) ?
|
||||
dsYellow :
|
||||
@ -259,6 +495,10 @@ void Signal::paint_label(QPainter &p, int y, int right, bool hover, int action)
|
||||
dsYellow :
|
||||
dsBlue);
|
||||
p.drawRect(lowTrig_rect);
|
||||
p.setBrush(((hover && action == EDGETRIG) || (_trig == EDGETRIG)) ?
|
||||
dsYellow :
|
||||
dsBlue);
|
||||
p.drawRect(edgeTrig_rect);
|
||||
|
||||
p.setPen(QPen(Qt::blue, 1, Qt::DotLine));
|
||||
p.setBrush(Qt::transparent);
|
||||
@ -268,6 +508,8 @@ void Signal::paint_label(QPainter &p, int y, int right, bool hover, int action)
|
||||
higTrig_rect.right(), higTrig_rect.bottom() - 3);
|
||||
p.drawLine(negTrig_rect.right(), negTrig_rect.top() + 3,
|
||||
negTrig_rect.right(), negTrig_rect.bottom() - 3);
|
||||
p.drawLine(lowTrig_rect.right(), lowTrig_rect.top() + 3,
|
||||
lowTrig_rect.right(), lowTrig_rect.bottom() - 3);
|
||||
|
||||
p.setPen(QPen(Qt::white, 2, Qt::SolidLine));
|
||||
p.setBrush(Qt::transparent);
|
||||
@ -290,6 +532,17 @@ void Signal::paint_label(QPainter &p, int y, int right, bool hover, int action)
|
||||
|
||||
p.drawLine(lowTrig_rect.left() + 5, lowTrig_rect.bottom() - 5,
|
||||
lowTrig_rect.right() - 5, lowTrig_rect.bottom() - 5);
|
||||
|
||||
p.drawLine(edgeTrig_rect.left() + 5, edgeTrig_rect.top() + 5,
|
||||
edgeTrig_rect.center().x() - 2, edgeTrig_rect.top() + 5);
|
||||
p.drawLine(edgeTrig_rect.center().x() + 2 , edgeTrig_rect.top() + 5,
|
||||
edgeTrig_rect.right() - 5, edgeTrig_rect.top() + 5);
|
||||
p.drawLine(edgeTrig_rect.center().x(), edgeTrig_rect.top() + 7,
|
||||
edgeTrig_rect.center().x(), edgeTrig_rect.bottom() - 7);
|
||||
p.drawLine(edgeTrig_rect.left() + 5, edgeTrig_rect.bottom() - 5,
|
||||
edgeTrig_rect.center().x() - 2, edgeTrig_rect.bottom() - 5);
|
||||
p.drawLine(edgeTrig_rect.center().x() + 2, edgeTrig_rect.bottom() - 5,
|
||||
edgeTrig_rect.right() - 5, edgeTrig_rect.bottom() - 5);
|
||||
} else if (_type == DS_GROUP || _type == DS_PROTOCOL) {
|
||||
const QRectF group_index_rect = get_rect("groupIndex", y, right);
|
||||
QString index_string;
|
||||
@ -311,40 +564,92 @@ void Signal::paint_label(QPainter &p, int y, int right, bool hover, int action)
|
||||
}
|
||||
p.setPen(Qt::white);
|
||||
p.drawText(group_index_rect, Qt::AlignRight | Qt::AlignVCenter, index_string);
|
||||
} else if (_type == DS_DSO) {
|
||||
const QRectF vDial_rect = get_rect("vDial", 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);
|
||||
|
||||
QColor vDial_color = _vDialActive ? dsActive : dsDisable;
|
||||
QColor hDial_color = _hDialActive ? dsActive : dsDisable;
|
||||
_vDial->paint(p, vDial_rect, vDial_color);
|
||||
_hDial->paint(p, hDial_rect, hDial_color);
|
||||
|
||||
p.setPen(Qt::transparent);
|
||||
p.setBrush((hover && action == CHEN) ? _colour.darker() : _colour);
|
||||
p.drawRect(chEn_rect);
|
||||
p.setPen(Qt::white);
|
||||
p.drawText(chEn_rect, Qt::AlignCenter | Qt::AlignVCenter, _active ? "EN" : "DIS");
|
||||
|
||||
p.setPen(Qt::transparent);
|
||||
p.setBrush(_active ? ((hover && action == ACDC) ? _colour.darker() : _colour) : dsDisable);
|
||||
p.drawRect(acdc_rect);
|
||||
p.setPen(Qt::white);
|
||||
p.drawText(acdc_rect, Qt::AlignCenter | Qt::AlignVCenter, _acCoupling ? "AC" : "DC");
|
||||
}
|
||||
|
||||
// Paint the label
|
||||
const QPointF points[] = {
|
||||
label_rect.topLeft(),
|
||||
label_rect.topRight(),
|
||||
QPointF(right, y),
|
||||
label_rect.bottomRight(),
|
||||
label_rect.bottomLeft()
|
||||
};
|
||||
if (_active) {
|
||||
const QPointF points[] = {
|
||||
label_rect.topLeft(),
|
||||
label_rect.topRight(),
|
||||
QPointF(right, (_type == DS_DSO) ? _zeroPos : y),
|
||||
label_rect.bottomRight(),
|
||||
label_rect.bottomLeft()
|
||||
};
|
||||
|
||||
p.setPen(Qt::transparent);
|
||||
p.setBrush(((hover && action == LABEL) || _selected) ? dsYellow : dsBlue);
|
||||
p.drawPolygon(points, countof(points));
|
||||
p.setPen(Qt::transparent);
|
||||
if (_type == DS_DSO)
|
||||
p.setBrush(((hover && action == LABEL) || _selected) ? _colour.darker() : _colour);
|
||||
else
|
||||
p.setBrush(((hover && action == LABEL) || _selected) ? dsYellow : dsBlue);
|
||||
p.drawPolygon(points, countof(points));
|
||||
|
||||
if ((hover && action == LABEL) || _selected) {
|
||||
p.setPen(QPen(dsBlue, 2, Qt::DotLine));
|
||||
p.setPen(QPen(Qt::blue, 1, Qt::DotLine));
|
||||
p.setBrush(Qt::transparent);
|
||||
p.drawPoint(label_rect.right(), label_rect.top() + 4);
|
||||
p.drawPoint(label_rect.right(), label_rect.top() + 8);
|
||||
p.drawPoint(label_rect.right(), label_rect.top() + 12);
|
||||
p.drawPoint(label_rect.right(), label_rect.top() + 16);
|
||||
}
|
||||
p.drawLine(label_rect.right(), label_rect.top() + 3,
|
||||
label_rect.right(), label_rect.bottom() - 3);
|
||||
|
||||
// Paint the text
|
||||
p.setPen(Qt::white);
|
||||
if (_type == DS_GROUP)
|
||||
p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "G");
|
||||
else if (_type == DS_ANALOG)
|
||||
p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "A");
|
||||
else if (_type == DS_PROTOCOL)
|
||||
p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "D");
|
||||
else
|
||||
p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, QString::number(_index_list.front()));
|
||||
// Paint the text
|
||||
p.setPen(Qt::white);
|
||||
if (_type == DS_GROUP)
|
||||
p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "G");
|
||||
else if (_type == DS_ANALOG)
|
||||
p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "A");
|
||||
else if (_type == DS_PROTOCOL)
|
||||
p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "D");
|
||||
else
|
||||
p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, QString::number(_index_list.front()));
|
||||
}
|
||||
}
|
||||
|
||||
void Signal::paint_trig(QPainter &p, int left, int right, bool hover)
|
||||
{
|
||||
if (_type == DS_DSO) {
|
||||
const QRectF label_rect = get_rect("dsoTrig", -1, right);
|
||||
// Paint the trig line
|
||||
if (_trig_en) {
|
||||
const QPointF points[] = {
|
||||
QPointF(right - label_rect.width()*1.5, _trig_vpos),
|
||||
label_rect.topLeft(),
|
||||
label_rect.topRight(),
|
||||
label_rect.bottomRight(),
|
||||
label_rect.bottomLeft()
|
||||
};
|
||||
|
||||
p.setPen(Qt::transparent);
|
||||
p.setBrush(_colour);
|
||||
p.drawPolygon(points, countof(points));
|
||||
|
||||
// paint the _trig_vpos line
|
||||
p.setPen(QPen(_colour, hover ? 2 : 1, Qt::DashLine));
|
||||
p.drawLine(left, _trig_vpos, right - label_rect.width()*1.5, _trig_vpos);
|
||||
|
||||
// Paint the text
|
||||
p.setPen(Qt::white);
|
||||
p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "T");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Signal::pt_in_rect(int y, int right, const QPoint &point)
|
||||
@ -355,11 +660,17 @@ int Signal::pt_in_rect(int y, int right, const QPoint &point)
|
||||
const QRectF higTrig = get_rect("higTrig", y, right);
|
||||
const QRectF negTrig = get_rect("negTrig", y, right);
|
||||
const QRectF lowTrig = get_rect("lowTrig", y, right);
|
||||
const QRectF label = get_rect("label", y, right);
|
||||
const QRectF edgeTrig = get_rect("edgeTrig", y, right);
|
||||
const QRectF label = get_rect("label", (_type == DS_DSO) ? _zeroPos : y, right);
|
||||
const QRectF vDial = get_rect("vDial", 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);
|
||||
const QRectF dsoTrig = get_rect("dsoTrig", 0, right);
|
||||
|
||||
if (color.contains(point))
|
||||
if (color.contains(point) && _active)
|
||||
return COLOR;
|
||||
else if (name.contains(point))
|
||||
else if (name.contains(point) && _active)
|
||||
return NAME;
|
||||
else if (posTrig.contains(point) && _type == DS_LOGIC)
|
||||
return POSTRIG;
|
||||
@ -369,8 +680,20 @@ int Signal::pt_in_rect(int y, int right, const QPoint &point)
|
||||
return NEGTRIG;
|
||||
else if (lowTrig.contains(point) && _type == DS_LOGIC)
|
||||
return LOWTRIG;
|
||||
else if (label.contains(point))
|
||||
else if (edgeTrig.contains(point) && _type == DS_LOGIC)
|
||||
return EDGETRIG;
|
||||
else if (label.contains(point) && _active)
|
||||
return LABEL;
|
||||
else if (vDial.contains(point) && _type == DS_DSO && _active)
|
||||
return VDIAL;
|
||||
else if (hDial.contains(point) && _type == DS_DSO && _active)
|
||||
return HDIAL;
|
||||
else if (chEn.contains(point) && _type == DS_DSO)
|
||||
return CHEN;
|
||||
else if (acdc.contains(point) && _type == DS_DSO && _active)
|
||||
return ACDC;
|
||||
else if (dsoTrig.contains(point) && _type == DS_DSO && _active)
|
||||
return DSOTRIG;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
@ -392,7 +715,8 @@ QRectF Signal::get_rect(const char *s, int y, int right)
|
||||
{
|
||||
const QSizeF color_size(SquareWidth, SquareWidth);
|
||||
const QSizeF name_size(right - get_leftWidth() - get_rightWidth(), SquareWidth);
|
||||
const QSizeF label_size(_text_size.width() + Margin, SquareWidth);
|
||||
//const QSizeF label_size(_text_size.width() + Margin, SquareWidth);
|
||||
const QSizeF label_size(SquareWidth, SquareWidth);
|
||||
|
||||
if (!strcmp(s, "name"))
|
||||
return QRectF(
|
||||
@ -402,38 +726,68 @@ QRectF Signal::get_rect(const char *s, int y, int right)
|
||||
else if (!strcmp(s, "label"))
|
||||
return QRectF(
|
||||
right - 1.5f * label_size.width(),
|
||||
y - label_size.height() / 2,
|
||||
y - SquareWidth / 2,
|
||||
label_size.width(), label_size.height());
|
||||
else if (!strcmp(s, "posTrig"))
|
||||
return QRectF(
|
||||
get_leftWidth() + name_size.width() + Margin,
|
||||
y - color_size.height() / 2,
|
||||
color_size.width(), color_size.height());
|
||||
y - SquareWidth / 2,
|
||||
SquareWidth, SquareWidth);
|
||||
else if (!strcmp(s, "higTrig"))
|
||||
return QRectF(
|
||||
get_leftWidth() + name_size.width() + SquareWidth + Margin,
|
||||
y - color_size.height() / 2,
|
||||
color_size.width(), color_size.height());
|
||||
y - SquareWidth / 2,
|
||||
SquareWidth, SquareWidth);
|
||||
else if (!strcmp(s, "negTrig"))
|
||||
return QRectF(
|
||||
get_leftWidth() + name_size.width() + 2 * SquareWidth + Margin,
|
||||
y - color_size.height() / 2,
|
||||
color_size.width(), color_size.height());
|
||||
y - SquareWidth / 2,
|
||||
SquareWidth, SquareWidth);
|
||||
else if (!strcmp(s, "lowTrig"))
|
||||
return QRectF(
|
||||
get_leftWidth() + name_size.width() + 3 * SquareWidth + Margin,
|
||||
y - color_size.height() / 2,
|
||||
color_size.width(), color_size.height());
|
||||
y - SquareWidth / 2,
|
||||
SquareWidth, SquareWidth);
|
||||
else if (!strcmp(s, "edgeTrig"))
|
||||
return QRectF(
|
||||
get_leftWidth() + name_size.width() + 4 * SquareWidth + Margin,
|
||||
y - SquareWidth / 2,
|
||||
SquareWidth, SquareWidth);
|
||||
else if (!strcmp(s, "groupIndex"))
|
||||
return QRectF(
|
||||
get_leftWidth() + name_size.width() + Margin,
|
||||
y - color_size.height() / 2,
|
||||
color_size.width() * 4, color_size.height());
|
||||
y - SquareWidth / 2,
|
||||
SquareWidth * SquareNum, SquareWidth);
|
||||
else if (!strcmp(s, "vDial"))
|
||||
return QRectF(
|
||||
get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin,
|
||||
y - SquareWidth * SquareNum,
|
||||
SquareWidth * (SquareNum-1), SquareWidth * (SquareNum-1));
|
||||
else if (!strcmp(s, "hDial"))
|
||||
return QRectF(
|
||||
get_leftWidth() + name_size.width() + SquareWidth*0.5 + Margin,
|
||||
y + SquareWidth * 1.5,
|
||||
SquareWidth * (SquareNum-1), SquareWidth * (SquareNum-1));
|
||||
else if (!strcmp(s, "chEn"))
|
||||
return QRectF(
|
||||
get_leftWidth() + name_size.width() + SquareWidth*0.75 + Margin,
|
||||
y - SquareWidth / 2,
|
||||
SquareWidth * 1.5, SquareWidth);
|
||||
else if (!strcmp(s, "acdc"))
|
||||
return QRectF(
|
||||
get_leftWidth() + name_size.width() + SquareWidth*2.75 + Margin,
|
||||
y - SquareWidth / 2,
|
||||
SquareWidth * 1.5, SquareWidth);
|
||||
else if (!strcmp(s, "dsoTrig"))
|
||||
return QRectF(
|
||||
right - label_size.width(),
|
||||
_trig_vpos - SquareWidth / 2,
|
||||
label_size.width(), label_size.height());
|
||||
else
|
||||
return QRectF(
|
||||
2,
|
||||
y - color_size.height() / 2,
|
||||
color_size.width(), color_size.height());
|
||||
y - SquareWidth / 2,
|
||||
SquareWidth, SquareWidth);
|
||||
}
|
||||
|
||||
} // namespace view
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <list>
|
||||
|
||||
#include "libsigrok4DSLogic/libsigrok.h"
|
||||
#include "dsldial.h"
|
||||
|
||||
namespace pv {
|
||||
|
||||
@ -56,26 +57,47 @@ namespace view {
|
||||
class Signal
|
||||
{
|
||||
private:
|
||||
static const int SquareWidth;
|
||||
static const int Margin;
|
||||
static const int SquareWidth = 20;
|
||||
static const int Margin = 3;
|
||||
static const int SquareNum = 5;
|
||||
|
||||
static const int COLOR;
|
||||
static const int NAME;
|
||||
static const int POSTRIG;
|
||||
static const int HIGTRIG;
|
||||
static const int NEGTRIG;
|
||||
static const int LOWTRIG;
|
||||
static const int LABEL;
|
||||
static const uint64_t vDialValueCount = 10;
|
||||
static const uint64_t vDialValueStep = 1000;
|
||||
static const uint64_t vDialUnitCount = 2;
|
||||
static const uint64_t hDialValueCount = 25;
|
||||
static const uint64_t hDialValueStep = 1000;
|
||||
static const uint64_t hDialUnitCount = 4;
|
||||
static const uint64_t vDialValue[vDialValueCount];
|
||||
static const QString vDialUnit[vDialUnitCount];
|
||||
|
||||
static const uint64_t hDialValue[hDialValueCount];
|
||||
static const QString hDialUnit[hDialUnitCount];
|
||||
|
||||
public:
|
||||
static const int COLOR = 1;
|
||||
static const int NAME = 2;
|
||||
static const int POSTRIG = 3;
|
||||
static const int HIGTRIG = 4;
|
||||
static const int NEGTRIG = 5;
|
||||
static const int LOWTRIG = 6;
|
||||
static const int EDGETRIG = 7;
|
||||
static const int LABEL = 8;
|
||||
static const int VDIAL = 9;
|
||||
static const int HDIAL = 10;
|
||||
static const int CHEN = 11;
|
||||
static const int ACDC = 12;
|
||||
static const int DSOTRIG = 13;
|
||||
|
||||
static const QColor dsBlue;
|
||||
static const QColor dsYellow;
|
||||
static const QColor dsRed;
|
||||
static const QColor dsGreen;
|
||||
static const QColor dsGray;
|
||||
static const QColor dsDisable;
|
||||
static const QColor dsActive;
|
||||
static const QColor dsLightBlue;
|
||||
static const QColor dsLightRed;
|
||||
static const QPen SignalAxisPen;
|
||||
static const QPen SignalAxisPen;
|
||||
|
||||
enum {DS_LOGIC = 0, DS_ANALOG, DS_GROUP, DS_PROTOCOL, DS_DSO};
|
||||
|
||||
@ -166,6 +188,32 @@ public:
|
||||
int get_trig() const;
|
||||
void set_trig(int trig);
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
bool get_vDialActive() const;
|
||||
void set_vDialActive(bool active);
|
||||
bool get_hDialActive() const;
|
||||
void set_hDialActive(bool active);
|
||||
bool go_vDialPre();
|
||||
bool go_vDialNext();
|
||||
bool go_hDialPre();
|
||||
bool go_hDialNext();
|
||||
uint64_t get_vDialValue() const;
|
||||
uint64_t get_hDialValue() const;
|
||||
uint16_t get_vDialSel() const;
|
||||
uint16_t get_hDialSel() const;
|
||||
bool get_acCoupling() const;
|
||||
void set_acCoupling(bool coupling);
|
||||
bool get_active() const;
|
||||
void set_active(bool active);
|
||||
int get_zeroPos() const;
|
||||
void set_zeroPos(int pos);
|
||||
int get_windowHeight() const;
|
||||
void set_windowHeight(int height);
|
||||
void set_trig_vpos(int value);
|
||||
int get_trig_vpos() const;
|
||||
|
||||
/**
|
||||
* Paints the signal with a QPainter
|
||||
* @param p the QPainter to paint into.
|
||||
@ -177,7 +225,7 @@ public:
|
||||
* the view in seconds.
|
||||
**/
|
||||
virtual void paint(QPainter &p, int y, int left, int right,
|
||||
double scale, double offset) = 0;
|
||||
double scale, double offset) = 0;
|
||||
|
||||
virtual const std::vector< std::pair<uint64_t, bool> > cur_edges() const = 0;
|
||||
|
||||
@ -200,9 +248,12 @@ public:
|
||||
* area.
|
||||
* @param hover true if the label is being hovered over by the mouse.
|
||||
*/
|
||||
virtual void paint_label(QPainter &p, int y, int right,
|
||||
virtual void paint_label(QPainter &p, int y, int right,
|
||||
bool hover, int action);
|
||||
|
||||
virtual void paint_trig(QPainter &p, int left, int right,
|
||||
bool hover);
|
||||
|
||||
/**
|
||||
* Determines if a point is in the header rect.
|
||||
* 1 - in color rect
|
||||
@ -221,6 +272,16 @@ public:
|
||||
int pt_in_rect(int y, int right,
|
||||
const QPoint &point);
|
||||
|
||||
/**
|
||||
* Computes the outline rectangle of a label.
|
||||
* @param p the QPainter to lay out text with.
|
||||
* @param y the y-coordinate of the signal.
|
||||
* @param right the x-coordinate of the right edge of the header
|
||||
* area.
|
||||
* @return Returns the rectangle of the signal label.
|
||||
*/
|
||||
QRectF get_rect(const char *s, int y, int right);
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
@ -239,16 +300,6 @@ private:
|
||||
*/
|
||||
void compute_text_size(QPainter &p);
|
||||
|
||||
/**
|
||||
* Computes the outline rectangle of a label.
|
||||
* @param p the QPainter to lay out text with.
|
||||
* @param y the y-coordinate of the signal.
|
||||
* @param right the x-coordinate of the right edge of the header
|
||||
* area.
|
||||
* @return Returns the rectangle of the signal label.
|
||||
*/
|
||||
QRectF get_rect(const char *s, int y, int right);
|
||||
|
||||
protected:
|
||||
int _type;
|
||||
std::list<int> _index_list;
|
||||
@ -266,6 +317,17 @@ protected:
|
||||
int _trig;
|
||||
|
||||
QSizeF _text_size;
|
||||
dslDial *_vDial;
|
||||
dslDial *_hDial;
|
||||
bool _vDialActive;
|
||||
bool _hDialActive;
|
||||
bool _acCoupling;
|
||||
bool _active;
|
||||
int _zeroPos;
|
||||
int _windowHeight;
|
||||
|
||||
int _trig_vpos;
|
||||
bool _trig_en;
|
||||
};
|
||||
|
||||
} // namespace view
|
||||
|
@ -105,6 +105,14 @@ View::View(SigSession &session, QWidget *parent) :
|
||||
this, SLOT(on_signals_moved()));
|
||||
connect(_header, SIGNAL(header_updated()),
|
||||
this, SLOT(header_updated()));
|
||||
connect(_header, SIGNAL(vDial_changed(quint16)),
|
||||
this, SLOT(vDial_changed(quint16)));
|
||||
connect(_header, SIGNAL(hDial_changed(quint16)),
|
||||
this, SLOT(hDial_changed(quint16)));
|
||||
connect(_header, SIGNAL(acdc_changed(quint16)),
|
||||
this, SLOT(acdc_changed(quint16)));
|
||||
connect(_header, SIGNAL(ch_changed(quint16)),
|
||||
this, SLOT(ch_changed(quint16)));
|
||||
|
||||
setViewportMargins(headerWidth(), RulerHeight, 0, 0);
|
||||
setViewport(_viewport);
|
||||
@ -176,8 +184,20 @@ void View::zoom(double steps, int offset)
|
||||
_preOffset = _offset;
|
||||
|
||||
const double cursor_offset = _offset + _scale * offset;
|
||||
_scale *= pow(3.0/2.0, -steps);
|
||||
_scale = max(min(_scale, _maxscale), _minscale);
|
||||
if (_session.get_device()->mode != DSO) {
|
||||
_scale *= pow(3.0/2.0, -steps);
|
||||
_scale = max(min(_scale, _maxscale), _minscale);
|
||||
} else {
|
||||
const vector< shared_ptr<Signal> > sigs(_session.get_signals());
|
||||
if (steps > 0.5) {
|
||||
BOOST_FOREACH(const shared_ptr<Signal> s, sigs)
|
||||
s->go_hDialNext();
|
||||
} else if(steps < -0.5) {
|
||||
BOOST_FOREACH(const shared_ptr<Signal> s, sigs)
|
||||
s->go_hDialPre();
|
||||
}
|
||||
_scale = sigs.at(0)->get_hDialValue() * pow(10, -9) * Viewport::NumSpanX / _viewport->width();
|
||||
}
|
||||
_offset = cursor_offset - _scale * offset;
|
||||
const double MinOffset = -(_scale * (_viewport->width() * (1 - MaxViewRate)));
|
||||
const double MaxOffset = _data_length * 1.0f / _session.get_last_sample_rate() -
|
||||
@ -185,6 +205,7 @@ void View::zoom(double steps, int offset)
|
||||
_offset = max(min(_offset, MaxOffset), MinOffset);
|
||||
|
||||
if (_scale != _preScale || _offset != _preOffset) {
|
||||
_header->update();
|
||||
_ruler->update();
|
||||
_viewport->update();
|
||||
update_scroll();
|
||||
@ -199,7 +220,9 @@ void View::set_scale_offset(double scale, double offset)
|
||||
_preScale = _scale;
|
||||
_preOffset = _offset;
|
||||
|
||||
_scale = max(min(scale, _maxscale), _minscale);
|
||||
if (_session.get_device()->mode != DSO)
|
||||
_scale = max(min(scale, _maxscale), _minscale);
|
||||
|
||||
const double MinOffset = -(_scale * (_viewport->width() * (1 - MaxViewRate)));
|
||||
const double MaxOffset = _data_length * 1.0f / _session.get_last_sample_rate()
|
||||
- _scale * (_viewport->width() * MaxViewRate);
|
||||
@ -380,9 +403,11 @@ void View::reset_signal_layout()
|
||||
const vector< boost::shared_ptr<Signal> > sigs(_session.get_signals());
|
||||
BOOST_FOREACH(boost::shared_ptr<Signal> s, sigs) {
|
||||
s->set_signalHeight(SignalHeight);
|
||||
s->set_windowHeight(_viewport->height());
|
||||
//s->set_v_offset(offset);
|
||||
//offset += SignalHeight + 2 * SignalMargin;
|
||||
s->set_v_offset(offset + s->get_order() * _spanY);
|
||||
s->set_zeroPos(_viewport->height()*0.5);
|
||||
}
|
||||
normalize_layout();
|
||||
}
|
||||
@ -439,7 +464,7 @@ int View::headerWidth()
|
||||
int maxNameWidth = 0;
|
||||
int maxLeftWidth = 0;
|
||||
int maxRightWidth = 0;
|
||||
|
||||
|
||||
QFont font = QApplication::font();
|
||||
QFontMetrics fm(font);
|
||||
int fontWidth=fm.width("A");
|
||||
@ -518,7 +543,8 @@ void View::data_updated()
|
||||
// Get the new data length
|
||||
_data_length = max(_session.get_total_sample_len(), (quint64)1000);
|
||||
_maxscale = (_data_length * 1.0f / _session.get_last_sample_rate()) / (_viewport->width() * MaxViewRate);
|
||||
_scale = min(_scale, _maxscale);
|
||||
if(_session.get_device()->mode != DSO)
|
||||
_scale = min(_scale, _maxscale);
|
||||
|
||||
setViewportMargins(headerWidth(), RulerHeight, 0, 0);
|
||||
update_margins();
|
||||
@ -555,7 +581,9 @@ void View::sample_rate_changed(quint64 sample_rate)
|
||||
{
|
||||
assert(sample_rate > 0);
|
||||
|
||||
_scale = (1.0f / sample_rate) / WellPixelsPerSample;
|
||||
if (_session.get_device()->mode != DSO)
|
||||
_scale = (1.0f / sample_rate) / WellPixelsPerSample;
|
||||
|
||||
_minscale = (1.0f / sample_rate) / (_viewport->width() * MaxViewRate);
|
||||
_offset = 0;
|
||||
_preScale = _scale;
|
||||
@ -574,7 +602,8 @@ void View::marker_time_changed()
|
||||
void View::on_signals_moved()
|
||||
{
|
||||
update_scroll();
|
||||
signals_moved();
|
||||
_viewport->update();
|
||||
//signals_moved();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -704,5 +733,39 @@ void View::on_state_changed(bool stop)
|
||||
_viewport->stop_trigger_timer();
|
||||
}
|
||||
|
||||
void View::vDial_changed(uint16_t channel)
|
||||
{
|
||||
if (channel == 0)
|
||||
_session.set_dso_ctrl(SR_CONF_VDIV0);
|
||||
else
|
||||
_session.set_dso_ctrl(SR_CONF_VDIV1);
|
||||
}
|
||||
|
||||
void View::hDial_changed(uint16_t channel)
|
||||
{
|
||||
const vector< shared_ptr<Signal> > sigs(_session.get_signals());
|
||||
_session.set_dso_ctrl(SR_CONF_TIMEBASE);
|
||||
_scale = sigs.at(channel)->get_hDialValue() * pow(10, -9) * Viewport::NumSpanX / _viewport->width();
|
||||
_ruler->update();
|
||||
_viewport->update();
|
||||
update_scroll();
|
||||
}
|
||||
|
||||
void View::acdc_changed(uint16_t channel)
|
||||
{
|
||||
if (channel == 0)
|
||||
_session.set_dso_ctrl(SR_CONF_COUPLING0);
|
||||
else
|
||||
_session.set_dso_ctrl(SR_CONF_COUPLING1);
|
||||
}
|
||||
|
||||
void View::ch_changed(uint16_t channel)
|
||||
{
|
||||
if (channel == 0)
|
||||
_session.set_dso_ctrl(SR_CONF_EN_CH0);
|
||||
else
|
||||
_session.set_dso_ctrl(SR_CONF_EN_CH1);
|
||||
}
|
||||
|
||||
} // namespace view
|
||||
} // namespace pv
|
||||
|
@ -187,7 +187,8 @@ private:
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
|
||||
public slots:
|
||||
void set_measure_en(int enable);
|
||||
void set_measure_en(int enable);
|
||||
void hDial_changed(quint16 channel);
|
||||
|
||||
private slots:
|
||||
|
||||
@ -209,6 +210,10 @@ private slots:
|
||||
|
||||
void set_trig_pos(quint64 trig_pos);
|
||||
|
||||
void vDial_changed(quint16 channel);
|
||||
void acdc_changed(quint16 channel);
|
||||
void ch_changed(quint16 channel);
|
||||
|
||||
private:
|
||||
|
||||
SigSession &_session;
|
||||
|
@ -105,19 +105,19 @@ void Viewport::paintEvent(QPaintEvent *event)
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
if (_view.session().get_device()->mode == LOGIC) {
|
||||
switch(_view.session().get_capture_state()) {
|
||||
case SigSession::Init:
|
||||
break;
|
||||
switch(_view.session().get_capture_state()) {
|
||||
case SigSession::Init:
|
||||
break;
|
||||
|
||||
case SigSession::Stopped:
|
||||
paintSignals(p);
|
||||
break;
|
||||
case SigSession::Stopped:
|
||||
paintSignals(p);
|
||||
break;
|
||||
|
||||
case SigSession::Running:
|
||||
//p.setRenderHint(QPainter::Antialiasing);
|
||||
paintProgress(p);
|
||||
break;
|
||||
}
|
||||
case SigSession::Running:
|
||||
//p.setRenderHint(QPainter::Antialiasing);
|
||||
paintProgress(p);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
paintSignals(p);
|
||||
}
|
||||
@ -161,8 +161,8 @@ void Viewport::paintEvent(QPaintEvent *event)
|
||||
p.setPen(Signal::dsGray);
|
||||
p.setPen(Qt::DotLine);
|
||||
|
||||
const double spanY =height() * 1.0f / 8;
|
||||
for (i = 1; i < 9; i++) {
|
||||
const double spanY =height() * 1.0f / 10;
|
||||
for (i = 1; i < 11; i++) {
|
||||
const double posY = spanY * i;
|
||||
p.drawLine(0, posY, width(), posY);
|
||||
const double miniSpanY = spanY / 5;
|
||||
@ -210,8 +210,9 @@ void Viewport::paintSignals(QPainter &p)
|
||||
p.setRenderHint(QPainter::Antialiasing, false);
|
||||
BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
|
||||
assert(s);
|
||||
s->paint(dbp, s->get_v_offset() - v_offset, 0, width(),
|
||||
_view.scale(), _view.offset());
|
||||
if (s->get_active())
|
||||
s->paint(dbp, ((s->get_type() == Signal::DS_DSO) ? s->get_zeroPos() + height()*0.5 : s->get_v_offset() - v_offset), 0, width(),
|
||||
_view.scale(), _view.offset());
|
||||
}
|
||||
// p.setRenderHint(QPainter::Antialiasing);
|
||||
// BOOST_FOREACH(const boost::shared_ptr<Signal> s, pro_sigs) {
|
||||
@ -223,6 +224,13 @@ void Viewport::paintSignals(QPainter &p)
|
||||
}
|
||||
p.drawPixmap(0, 0, pixmap);
|
||||
|
||||
// plot trig line in DSO mode
|
||||
BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
|
||||
assert(s);
|
||||
if (s->get_active() && s->get_type() == Signal::DS_DSO)
|
||||
s->paint_trig(p, 0, width(), qAbs(_mouse_point.y() - s->get_trig_vpos()) <= HitCursorMargin );
|
||||
}
|
||||
|
||||
// plot cursors
|
||||
if (_view.cursors_shown()) {
|
||||
list<Cursor*>::iterator i = _view.get_cursorList().begin();
|
||||
@ -391,6 +399,20 @@ void Viewport::mousePressEvent(QMouseEvent *event)
|
||||
// if (!_view.get_ruler()->get_grabbed_cursor()) {
|
||||
// _zoom_rect_visible = true;
|
||||
// }
|
||||
|
||||
const vector< shared_ptr<Signal> > sigs(_view.session().get_signals());
|
||||
BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
|
||||
assert(s);
|
||||
if (s->get_active() &&
|
||||
s->get_type() == Signal::DS_DSO &&
|
||||
qAbs(_mouse_point.y() - s->get_trig_vpos()) <= HitCursorMargin) {
|
||||
if (_drag_sig)
|
||||
_drag_sig.reset();
|
||||
else
|
||||
_drag_sig = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
}
|
||||
@ -398,7 +420,7 @@ void Viewport::mousePressEvent(QMouseEvent *event)
|
||||
void Viewport::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
assert(event);
|
||||
|
||||
_mouse_point = event->pos();
|
||||
if (event->buttons() & Qt::RightButton) {
|
||||
_zoom_rect = QRectF(_mouse_down_point, event->pos());
|
||||
_zoom_rect_visible = true;
|
||||
@ -409,16 +431,35 @@ void Viewport::mouseMoveEvent(QMouseEvent *event)
|
||||
_mouse_down_offset +
|
||||
(_mouse_down_point - event->pos()).x() *
|
||||
_view.scale());
|
||||
|
||||
measure();
|
||||
}
|
||||
|
||||
if (!(event->buttons() || Qt::NoButton)) {
|
||||
if (_drag_sig) {
|
||||
uint16_t trig_value = 0;
|
||||
int vpos = _mouse_point.y();
|
||||
if (vpos < 0)
|
||||
vpos = 0;
|
||||
else if (vpos > height())
|
||||
vpos = height();
|
||||
_drag_sig->set_trig_vpos(vpos);
|
||||
|
||||
const vector< shared_ptr<Signal> > sigs(_view.session().get_signals());
|
||||
BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
|
||||
assert(s);
|
||||
if (s->get_active() &&
|
||||
s->get_type() == Signal::DS_DSO) {
|
||||
trig_value += (((uint16_t)(255 - s->get_trig_vpos()*1.0/height()*255)) << 8*s->get_index());
|
||||
}
|
||||
}
|
||||
sr_config_set(_view.session().get_device(),
|
||||
SR_CONF_TRIGGER_VALUE, g_variant_new_uint16(trig_value));
|
||||
}
|
||||
|
||||
TimeMarker* grabbed_marker = _view.get_ruler()->get_grabbed_cursor();
|
||||
if (_view.cursors_shown() && grabbed_marker) {
|
||||
grabbed_marker->set_time(_view.offset() + _view.hover_point().x() * _view.scale());
|
||||
}
|
||||
|
||||
measure();
|
||||
}
|
||||
|
||||
@ -472,6 +513,7 @@ void Viewport::wheelEvent(QWheelEvent *event)
|
||||
void Viewport::leaveEvent(QEvent *)
|
||||
{
|
||||
_measure_shown = false;
|
||||
_mouse_point = QPoint(-1, -1);
|
||||
//_view.show_cursors(false);
|
||||
update();
|
||||
}
|
||||
|
@ -24,6 +24,9 @@
|
||||
#ifndef DSLOGIC_PV_VIEW_VIEWPORT_H
|
||||
#define DSLOGIC_PV_VIEW_VIEWPORT_H
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
|
||||
#include <QTimer>
|
||||
#include <QWidget>
|
||||
#include <stdint.h>
|
||||
@ -35,13 +38,14 @@ class SigSession;
|
||||
namespace pv {
|
||||
namespace view {
|
||||
|
||||
class Signal;
|
||||
class View;
|
||||
|
||||
class Viewport : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
public:
|
||||
static const int HitCursorMargin;
|
||||
static const int NumSpanY;
|
||||
static const int NumMiniSpanY;
|
||||
@ -88,6 +92,7 @@ private:
|
||||
View &_view;
|
||||
|
||||
quint64 _total_receive_len;
|
||||
QPoint _mouse_point;
|
||||
QPoint _mouse_down_point;
|
||||
double _mouse_down_offset;
|
||||
double _curScale;
|
||||
@ -115,6 +120,8 @@ private:
|
||||
QTimer trigger_timer;
|
||||
bool triggered;
|
||||
int timer_cnt;
|
||||
|
||||
boost::shared_ptr<Signal> _drag_sig;
|
||||
};
|
||||
|
||||
} // namespace view
|
||||
|
Binary file not shown.
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
palette {
|
||||
background: rgb(17, 133, 209, 255);
|
||||
disabled: rgb(232, 232, 230, 255);
|
||||
disabled: rgb(200, 200, 200, 255);
|
||||
}
|
||||
|
||||
QMainWindow {
|
||||
@ -77,7 +77,7 @@ QSpinBox {
|
||||
QLineEdit:disabled,
|
||||
QComboBox:disabled,
|
||||
QSpinBox:disabled {
|
||||
background-color: rgb(232, 232, 230, 255);
|
||||
background-color: rgb(200, 200, 200, 255);
|
||||
}
|
||||
|
||||
QComboBox:!editable {
|
||||
@ -163,7 +163,7 @@ QGroupBox::title
|
||||
}
|
||||
QGroupBox:disabled
|
||||
{
|
||||
color: rgb(232, 232, 230, 255);
|
||||
color: rgb(200, 200, 200, 255);
|
||||
}
|
||||
|
||||
QDockWidget > QWidget > QTabWidget::pane{
|
||||
@ -175,7 +175,7 @@ QDockWidget > QWidget > QTabWidget::pane{
|
||||
}
|
||||
|
||||
QDockWidget > QWidget > QTabWidget::pane:disabled{
|
||||
border: 1px solid rgb(232, 232, 230, 255);
|
||||
border: 1px solid rgb(200, 200, 200, 255);
|
||||
border-right-color: rgb(17, 133, 209, 255); /* same as the pane color */
|
||||
}
|
||||
|
||||
@ -203,7 +203,7 @@ QDockWidget > QWidget > QTabWidget > QTabBar::tab:selected
|
||||
}
|
||||
QDockWidget > QWidget > QTabWidget > QTabBar::tab:disabled
|
||||
{
|
||||
color: rgb(232, 232, 230, 50);
|
||||
color: rgb(200, 200, 200, 50);
|
||||
border: 1px solid rgb(232, 232, 230, 255);
|
||||
background: transparent;
|
||||
border-left-color: rgb(17, 133, 209, 255); /* same as the pane color */
|
||||
@ -213,25 +213,29 @@ QCheckBox,
|
||||
QRadioButton,
|
||||
QLabel {
|
||||
border: none;
|
||||
color: white;
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
QCheckBox::checked,
|
||||
QRadioButton::checked {
|
||||
color: black;
|
||||
}
|
||||
|
||||
QLabel,
|
||||
QCheckBox::unchecked,
|
||||
QRadioButton::unchecked {
|
||||
color: white;
|
||||
}
|
||||
|
||||
QCheckBox,
|
||||
QLabel {
|
||||
padding: 1px 1px 1px 1px;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
QCheckBox::indicator:checked {
|
||||
image: url(:icons/checkbox.png);
|
||||
}
|
||||
QRadioButton::indicator:checked {
|
||||
image: url(:icons/radiobutton.png);
|
||||
}
|
||||
|
||||
QLabel:disabled {
|
||||
color: rgb(232, 232, 230, 255);
|
||||
color: rgb(200, 200, 200, 255);
|
||||
}
|
||||
|
||||
QSlider::groove:horizontal {
|
||||
|
@ -2,7 +2,8 @@
|
||||
## This file is part of the PulseView project.
|
||||
##
|
||||
## Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
|
||||
## Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>
|
||||
## Copyright (C) 2012-2013 Alexandru Gagniuc <mr.nuke.me@gmail.com>
|
||||
## Copyright (C) 2013-2014 DreamSourceLab <support@dreamsourcelab.com>
|
||||
##
|
||||
## This program is free software: you can redistribute it and/or modify
|
||||
## it under the terms of the GNU General Public License as published by
|
||||
@ -18,35 +19,293 @@
|
||||
## along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
##
|
||||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
include(FindPkgConfig)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
project(DSLogic)
|
||||
|
||||
#===============================================================================
|
||||
#= User Options
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
option(DISABLE_WERROR "Build without -Werror" TRUE)
|
||||
option(ENABLE_SIGNALS "Build with UNIX signals" TRUE)
|
||||
option(ENABLE_TESTS "Enable unit tests" FALSE)
|
||||
option(STATIC_PKGDEPS_LIBS "Statically link to (pkgconfig) libraries" FALSE)
|
||||
|
||||
if(WIN32)
|
||||
# On Windows/MinGW we need to statically link to libraries.
|
||||
# This option is user configurable, but enable it by default on win32.
|
||||
set(STATIC_PKGDEPS_LIBS TRUE)
|
||||
|
||||
# For boost-thread we need two additional settings on win32:
|
||||
set(Boost_USE_STATIC_LIBS on)
|
||||
add_definitions(-DBOOST_THREAD_USE_LIB)
|
||||
|
||||
# Windsws does not support UNIX signals
|
||||
set(ENABLE_SIGNALS FALSE)
|
||||
endif()
|
||||
|
||||
#===============================================================================
|
||||
#= Dependencies
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
list(APPEND PKGDEPS
|
||||
libsigrok4DSLogic>=0.2.0
|
||||
libusb-1.0>=1.0.16
|
||||
)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules/")
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(PKGDEPS REQUIRED ${PKGDEPS})
|
||||
|
||||
find_package(Qt4 REQUIRED)
|
||||
|
||||
# Find the platform's thread library (needed for boost-thread).
|
||||
# This will set ${CMAKE_THREAD_LIBS_INIT} to the correct, OS-specific value.
|
||||
find_package(Threads)
|
||||
|
||||
find_package(Boost 1.46 COMPONENTS unit_test_framework REQUIRED)
|
||||
if(WIN32)
|
||||
# On Windows/MinGW the we need to use 'thread_win32' instead of 'thread'.
|
||||
# The library is named libboost_thread_win32* (not libboost_thread*).
|
||||
find_package(Boost 1.42 COMPONENTS system thread_win32 REQUIRED)
|
||||
else()
|
||||
find_package(Boost 1.42 COMPONENTS system thread REQUIRED)
|
||||
endif()
|
||||
|
||||
set(pulseview_TEST_SOURCES
|
||||
${PROJECT_SOURCE_DIR}/pv/data/analogsnapshot.cpp
|
||||
${PROJECT_SOURCE_DIR}/pv/data/snapshot.cpp
|
||||
${PROJECT_SOURCE_DIR}/pv/data/logicsnapshot.cpp
|
||||
data/analogsnapshot.cpp
|
||||
data/logicsnapshot.cpp
|
||||
test.cpp
|
||||
find_package(libusb-1.0 REQUIRED)
|
||||
|
||||
#===============================================================================
|
||||
#= Config Header
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
set(DS_TITLE DSLogic)
|
||||
set(DS_DESCRIPTION "A GUI for DSLogic")
|
||||
|
||||
set(DS_VERSION_MAJOR 0)
|
||||
set(DS_VERSION_MINOR 3)
|
||||
set(DS_VERSION_MICRO 0)
|
||||
set(DS_VERSION_STRING
|
||||
${DS_VERSION_MAJOR}.${DS_VERSION_MINOR}.${DS_VERSION_MICRO}
|
||||
)
|
||||
|
||||
add_definitions(-DBOOST_TEST_DYN_LINK)
|
||||
configure_file (
|
||||
${PROJECT_SOURCE_DIR}/config.h.in
|
||||
${PROJECT_BINARY_DIR}/config.h
|
||||
)
|
||||
|
||||
#===============================================================================
|
||||
#= Sources
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
set(DSLogic_SOURCES
|
||||
main.cpp
|
||||
pv/devicemanager.cpp
|
||||
pv/mainwindow.cpp
|
||||
pv/sigsession.cpp
|
||||
pv/data/analog.cpp
|
||||
pv/data/analogsnapshot.cpp
|
||||
pv/data/group.cpp
|
||||
pv/data/groupsnapshot.cpp
|
||||
pv/data/logic.cpp
|
||||
pv/data/logicsnapshot.cpp
|
||||
pv/data/signaldata.cpp
|
||||
pv/data/snapshot.cpp
|
||||
pv/data/dso.cpp
|
||||
pv/data/dsosnapshot.cpp
|
||||
pv/decoder/decoder.cpp
|
||||
pv/decoder/decoderfactory.cpp
|
||||
pv/decoder/democonfig.cpp
|
||||
pv/decoder/ds1wire.cpp
|
||||
pv/decoder/dsdmx512.cpp
|
||||
pv/decoder/dsi2c.cpp
|
||||
pv/decoder/dsserial.cpp
|
||||
pv/decoder/dsspi.cpp
|
||||
pv/dialogs/about.cpp
|
||||
pv/dialogs/connect.cpp
|
||||
pv/dialogs/deviceoptions.cpp
|
||||
pv/dialogs/search.cpp
|
||||
pv/dock/fakelineedit.cpp
|
||||
pv/dock/measuredock.cpp
|
||||
pv/dock/protocoldock.cpp
|
||||
pv/dock/searchdock.cpp
|
||||
pv/dock/triggerdock.cpp
|
||||
pv/prop/bool.cpp
|
||||
pv/prop/double.cpp
|
||||
pv/prop/enum.cpp
|
||||
pv/prop/int.cpp
|
||||
pv/prop/property.cpp
|
||||
pv/prop/binding/binding.cpp
|
||||
pv/prop/binding/binding_deviceoptions.cpp
|
||||
pv/toolbars/devicebar.cpp
|
||||
pv/toolbars/filebar.cpp
|
||||
pv/toolbars/logobar.cpp
|
||||
pv/toolbars/samplingbar.cpp
|
||||
pv/toolbars/trigbar.cpp
|
||||
pv/view/analogsignal.cpp
|
||||
pv/view/cursor.cpp
|
||||
pv/view/groupsignal.cpp
|
||||
pv/view/header.cpp
|
||||
pv/view/logicsignal.cpp
|
||||
pv/view/protocolsignal.cpp
|
||||
pv/view/ruler.cpp
|
||||
pv/view/signal.cpp
|
||||
pv/view/timemarker.cpp
|
||||
pv/view/view.cpp
|
||||
pv/view/viewport.cpp
|
||||
pv/view/dsosignal.cpp
|
||||
pv/view/dsldial.cpp
|
||||
pv/dock/dsotriggerdock.cpp
|
||||
)
|
||||
|
||||
set(DSLogic_HEADERS
|
||||
pv/sigsession.h
|
||||
pv/mainwindow.h
|
||||
pv/decoder/democonfig.h
|
||||
pv/dock/fakelineedit.h
|
||||
pv/dock/measuredock.h
|
||||
pv/dock/protocoldock.h
|
||||
pv/dock/searchdock.h
|
||||
pv/dock/triggerdock.h
|
||||
pv/dialogs/about.h
|
||||
pv/dialogs/connect.h
|
||||
pv/dialogs/deviceoptions.h
|
||||
pv/dialogs/search.h
|
||||
pv/toolbars/samplingbar.h
|
||||
pv/toolbars/devicebar.h
|
||||
pv/toolbars/filebar.h
|
||||
pv/toolbars/logobar.h
|
||||
pv/toolbars/trigbar.h
|
||||
pv/data/dso.h
|
||||
pv/data/dsosnapshot.h
|
||||
pv/view/cursor.h
|
||||
pv/view/header.h
|
||||
pv/view/ruler.h
|
||||
pv/view/timemarker.h
|
||||
pv/view/groupsignal.h
|
||||
pv/view/protocolsignal.h
|
||||
pv/view/view.h
|
||||
pv/view/dsosignal.h
|
||||
pv/view/viewport.h
|
||||
pv/view/dsldial.h
|
||||
pv/dock/dsotriggerdock.h
|
||||
)
|
||||
|
||||
set(DSLogic_FORMS
|
||||
pv/dialogs/about.ui
|
||||
pv/decoder/dmx512config.ui
|
||||
pv/decoder/i2cconfig.ui
|
||||
pv/decoder/serialconfig.ui
|
||||
pv/decoder/spiconfig.ui
|
||||
pv/decoder/wire1config.ui
|
||||
)
|
||||
|
||||
set(DSLogic_RESOURCES
|
||||
DSLogic.qrc
|
||||
)
|
||||
|
||||
qt4_wrap_cpp(DSLogic_HEADERS_MOC ${DSLogic_HEADERS})
|
||||
qt4_wrap_ui(DSLogic_FORMS_HEADERS ${DSLogic_FORMS})
|
||||
qt4_add_resources(DSLogic_RESOURCES_RCC ${DSLogic_RESOURCES})
|
||||
|
||||
include(${QT_USE_FILE})
|
||||
|
||||
#===============================================================================
|
||||
#= Global Definitions
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
add_definitions(${QT_DEFINITIONS})
|
||||
add_definitions(-Wall -Wextra -Wno-return-type -Wno-ignored-qualifiers)
|
||||
|
||||
if(NOT DISABLE_WERROR)
|
||||
add_definitions(-Werror)
|
||||
endif()
|
||||
|
||||
#===============================================================================
|
||||
#= Global Include Directories
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${Boost_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(PULSEVIEW_LINK_LIBS
|
||||
if(STATIC_PKGDEPS_LIBS)
|
||||
include_directories(${PKGDEPS_STATIC_INCLUDE_DIRS})
|
||||
else()
|
||||
include_directories(${PKGDEPS_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
#===============================================================================
|
||||
#= Linker Configuration
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
link_directories(${Boost_LIBRARY_DIRS})
|
||||
|
||||
set(DSLOGIC_LINK_LIBS
|
||||
${Boost_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${QT_LIBRARIES}
|
||||
${LIBUSB_1_LIBRARIES}
|
||||
)
|
||||
|
||||
add_executable(pulseview-test
|
||||
${pulseview_TEST_SOURCES}
|
||||
if(STATIC_PKGDEPS_LIBS)
|
||||
link_directories(${PKGDEPS_STATIC_LIBRARY_DIRS})
|
||||
list(APPEND DSLOGIC_LINK_LIBS ${PKGDEPS_STATIC_LIBRARIES})
|
||||
else()
|
||||
link_directories(${PKGDEPS_LIBRARY_DIRS})
|
||||
list(APPEND DSLOGIC_LINK_LIBS ${PKGDEPS_LIBRARIES})
|
||||
endif()
|
||||
|
||||
add_executable(${PROJECT_NAME}
|
||||
${DSLogic_SOURCES}
|
||||
${DSLogic_HEADERS_MOC}
|
||||
${DSLogic_FORMS_HEADERS}
|
||||
${DSLogic_RESOURCES_RCC}
|
||||
)
|
||||
|
||||
target_link_libraries(pulseview-test ${PULSEVIEW_LINK_LIBS})
|
||||
target_link_libraries(${PROJECT_NAME} ${DSLOGIC_LINK_LIBS})
|
||||
|
||||
if(WIN32)
|
||||
# Pass -mwindows so that no "DOS box" will open when PulseView is started.
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "-mwindows")
|
||||
endif()
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES INSTALL_RPATH "/usr/local/lib")
|
||||
|
||||
#===============================================================================
|
||||
#= Installation
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# Install the executable.
|
||||
install(TARGETS ${PROJECT_NAME} DESTINATION bin/)
|
||||
install(FILES res/DSLogic.fw DESTINATION bin/res/)
|
||||
install(FILES res/DSLogic.bin DESTINATION bin/res/)
|
||||
|
||||
#===============================================================================
|
||||
#= Packaging (handled by CPack)
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR ${DS_VERSION_MAJOR})
|
||||
set(CPACK_PACKAGE_VERSION_MINOR ${DS_VERSION_MINOR})
|
||||
set(CPACK_PACKAGE_VERSION_PATCH ${DS_VERSION_MICRO})
|
||||
set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_CURRENT_SOURCE_DIR}/README)
|
||||
set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/COPYING)
|
||||
set(CPACK_SOURCE_IGNORE_FILES ${CMAKE_CURRENT_BINARY_DIR} ".gitignore" ".git")
|
||||
set(CPACK_SOURCE_PACKAGE_FILE_NAME
|
||||
"${CMAKE_PROJECT_NAME}-${DS_VERSION_MAJOR}.${DS_VERSION_MINOR}.${DS_VERSION_MICRO}")
|
||||
set(CPACK_SOURCE_GENERATOR "TGZ")
|
||||
|
||||
include(CPack)
|
||||
|
||||
#===============================================================================
|
||||
#= Tests
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
if(ENABLE_TESTS)
|
||||
add_subdirectory(test)
|
||||
enable_testing()
|
||||
add_test(test ${CMAKE_CURRENT_BINARY_DIR}/test/DSLogic-test)
|
||||
endif(ENABLE_TESTS)
|
||||
|
674
DSLogic-gui/test/COPYING
Normal file
674
DSLogic-gui/test/COPYING
Normal file
@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
49
DSLogic-gui/test/INSTALL
Normal file
49
DSLogic-gui/test/INSTALL
Normal file
@ -0,0 +1,49 @@
|
||||
-------------------------------------------------------------------------------
|
||||
INSTALL
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
- git
|
||||
- g++
|
||||
- make
|
||||
- libtool
|
||||
- pkg-config >= 0.22
|
||||
- cmake >= 2.6
|
||||
- libglib >= 2.28.0
|
||||
- Qt >= 4.5
|
||||
- libboost >= 1.42 (including the following libs):
|
||||
- libboost-system
|
||||
- libboost-thread
|
||||
- libsigrok4DSLogic >= 0.2.0
|
||||
|
||||
|
||||
Building and installing
|
||||
-----------------------
|
||||
Get the DSLogic-gui source code from: www.dreamsourcelab.com/download.html
|
||||
In order to build it, run:
|
||||
|
||||
$ cd DSLogic-gui
|
||||
$ cmake .
|
||||
$ make
|
||||
|
||||
For installing PulseView:
|
||||
|
||||
$ make install
|
||||
|
||||
See the following wiki page for more (OS-specific) instructions:
|
||||
|
||||
http://sigrok.org/wiki/Building
|
||||
|
||||
|
||||
Creating a source distribution package
|
||||
--------------------------------------
|
||||
|
||||
In order to build a source package begin with an unconfigured source tree.
|
||||
|
||||
$ mkdir dist
|
||||
$ cd dist
|
||||
$ cmake ..
|
||||
$ make package_source
|
||||
|
5
DSLogic-gui/test/NEWS
Normal file
5
DSLogic-gui/test/NEWS
Normal file
@ -0,0 +1,5 @@
|
||||
0.1.0 (2013-12-15)
|
||||
------------------
|
||||
|
||||
* Initial release.
|
||||
|
72
DSLogic-gui/test/README
Normal file
72
DSLogic-gui/test/README
Normal file
@ -0,0 +1,72 @@
|
||||
-------------------------------------------------------------------------------
|
||||
README
|
||||
-------------------------------------------------------------------------------
|
||||
DSLogic-gui is GUI for DSLogic software, it's based on PulseView
|
||||
from the sigrok project.
|
||||
|
||||
The sigrok project aims at creating a portable, cross-platform,
|
||||
Free/Libre/Open-Source signal analysis software suite that supports various
|
||||
device types (such as logic analyzers, oscilloscopes, multimeters, and more).
|
||||
|
||||
PulseView is a Qt-based LA/scope/MSO GUI for sigrok.
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
DSLogic-gui is in a usable state and has had official tarball releases.
|
||||
|
||||
However, it is still work in progress. Some basic functionality
|
||||
is available and working, but other things are still on the TODO list.
|
||||
|
||||
|
||||
Copyright and license
|
||||
---------------------
|
||||
|
||||
DSLogic-gui is licensed under the terms of the GNU General Public License
|
||||
(GPL), version 3 or later.
|
||||
|
||||
While some individual source code files are licensed under the GPLv2+, and
|
||||
some files are licensed under the GPLv3+, this doesn't change the fact that
|
||||
the program as a whole is licensed under the terms of the GPLv3+ (e.g. also
|
||||
due to the fact that it links against GPLv3+ libraries).
|
||||
|
||||
Please see the individual source files for the full list of copyright holders.
|
||||
|
||||
|
||||
Copyright notices
|
||||
-----------------
|
||||
|
||||
A copyright notice indicating a range of years, must be interpreted as having
|
||||
had copyrightable material added in each of those years.
|
||||
|
||||
Example:
|
||||
|
||||
Copyright (C) 2010-2013 Contributor Name
|
||||
|
||||
is to be interpreted as
|
||||
|
||||
Copyright (C) 2010,2011,2012,2013 Contributor Name
|
||||
|
||||
|
||||
Mailing lists
|
||||
-------------
|
||||
|
||||
There are two mailing lists for sigrok/PulseView:
|
||||
|
||||
https://lists.sourceforge.net/lists/listinfo/sigrok-devel
|
||||
https://lists.sourceforge.net/lists/listinfo/sigrok-commits
|
||||
|
||||
|
||||
IRC
|
||||
---
|
||||
|
||||
You can find the sigrok developers in the #sigrok IRC channel on Freenode.
|
||||
|
||||
|
||||
Website
|
||||
-------
|
||||
|
||||
http://sigrok.org/wiki/PulseView
|
||||
http://dreamsourcelab.com
|
||||
|
34
DSLogic-gui/test/config.h.in
Normal file
34
DSLogic-gui/test/config.h.in
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* This file is part of the PulseView project.
|
||||
*
|
||||
* Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _DSLOGIC_CONFIG_H
|
||||
#define _DSLOGIC_CONFIG_H
|
||||
|
||||
/* Application details */
|
||||
#define DS_TITLE "@DS_TITLE@"
|
||||
#define DS_DESCRIPTION "@DS_DESCRIPTION@"
|
||||
#define DS_BIN_NAME "@PROJECT_NAME@"
|
||||
|
||||
/* DSLogic version information */
|
||||
#define DS_VERSION_MAJOR @DS_VERSION_MAJOR@
|
||||
#define DS_VERSION_MINOR @DS_VERSION_MINOR@
|
||||
#define DS_VERSION_MICRO @DS_VERSION_MICRO@
|
||||
#define DS_VERSION_STRING "@DS_VERSION_STRING@"
|
||||
|
||||
#endif
|
32
DSLogic-gui/test/extdef.h
Normal file
32
DSLogic-gui/test/extdef.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* This file is part of the DSLogic-gui project.
|
||||
* DSLogic-gui is based on PulseView.
|
||||
*
|
||||
* Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
|
||||
* 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_EXTDEF_H
|
||||
#define DSLOGIC_EXTDEF_H
|
||||
|
||||
#define countof(x) (sizeof(x)/sizeof(x[0]))
|
||||
|
||||
#define begin_element(x) (&x[0])
|
||||
#define end_element(x) (&x[countof(x)])
|
||||
|
||||
#endif // DSLOGIC_EXTDEF_H
|
163
DSLogic-gui/test/main.cpp
Normal file
163
DSLogic-gui/test/main.cpp
Normal file
@ -0,0 +1,163 @@
|
||||
/*
|
||||
* This file is part of the DSLogic-gui project.
|
||||
* DSLogic-gui is based on PulseView.
|
||||
*
|
||||
* Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
|
||||
* 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
|
||||
*/
|
||||
|
||||
|
||||
#ifdef ENABLE_SIGROKDECODE
|
||||
#include <libsigrokdecode/libsigrokdecode.h> /* First, so we avoid a _POSIX_C_SOURCE warning. */
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <libsigrok4DSLogic/libsigrok.h>
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
#include <QtGui/QApplication>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
|
||||
#include "pv/devicemanager.h"
|
||||
#include "pv/mainwindow.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
void usage()
|
||||
{
|
||||
fprintf(stdout,
|
||||
"Usage:\n"
|
||||
" %s [OPTION…] [FILE] — %s\n"
|
||||
"\n"
|
||||
"Help Options:\n"
|
||||
" -l, --loglevel Set libsigrok/libsigrokdecode loglevel\n"
|
||||
" -V, --version Show release version\n"
|
||||
" -h, -?, --help Show help option\n"
|
||||
"\n", DS_BIN_NAME, DS_DESCRIPTION);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
struct sr_context *sr_ctx = NULL;
|
||||
const char *open_file = NULL;
|
||||
|
||||
QApplication a(argc, argv);
|
||||
|
||||
// Set some application metadata
|
||||
QApplication::setApplicationVersion(DS_VERSION_STRING);
|
||||
QApplication::setApplicationName("DSLogic(Beta)");
|
||||
QApplication::setOrganizationDomain("http://www.DreamSourceLab.com");
|
||||
|
||||
// Parse arguments
|
||||
while (1) {
|
||||
static const struct option long_options[] = {
|
||||
{"loglevel", required_argument, 0, 'l'},
|
||||
{"version", no_argument, 0, 'V'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
const int c = getopt_long(argc, argv,
|
||||
"l:Vh?", long_options, NULL);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'l':
|
||||
{
|
||||
const int loglevel = atoi(optarg);
|
||||
sr_log_loglevel_set(loglevel);
|
||||
|
||||
#ifdef ENABLE_SIGROKDECODE
|
||||
srd_log_loglevel_set(loglevel);
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'V':
|
||||
// Print version info
|
||||
fprintf(stdout, "%s %s\n", DS_TITLE, DS_VERSION_STRING);
|
||||
return 0;
|
||||
|
||||
case 'h':
|
||||
case '?':
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc - optind > 1) {
|
||||
fprintf(stderr, "Only one file can be openened.\n");
|
||||
return 1;
|
||||
} else if (argc - optind == 1)
|
||||
open_file = argv[argc - 1];
|
||||
|
||||
// Initialise libsigrok
|
||||
if (sr_init(&sr_ctx) != SR_OK) {
|
||||
qDebug() << "ERROR: libsigrok init failed.";
|
||||
return 1;
|
||||
}
|
||||
|
||||
do {
|
||||
|
||||
#ifdef ENABLE_SIGROKDECODE
|
||||
// Initialise libsigrokdecode
|
||||
if (srd_init(NULL) != SRD_OK) {
|
||||
qDebug() << "ERROR: libsigrokdecode init failed.";
|
||||
break;
|
||||
}
|
||||
|
||||
// Load the protocol decoders
|
||||
srd_decoder_load_all();
|
||||
#endif
|
||||
|
||||
try {
|
||||
// Create the device manager, initialise the drivers
|
||||
pv::DeviceManager device_manager(sr_ctx);
|
||||
|
||||
// Initialise the main window
|
||||
pv::MainWindow w(device_manager, open_file);
|
||||
QFile qss(":/stylesheet.qss");
|
||||
qss.open(QFile::ReadOnly);
|
||||
a.setStyleSheet(qss.readAll());
|
||||
qss.close();
|
||||
w.show();
|
||||
|
||||
// Run the application
|
||||
ret = a.exec();
|
||||
|
||||
} catch(std::exception e) {
|
||||
qDebug() << e.what();
|
||||
}
|
||||
|
||||
#ifdef ENABLE_SIGROKDECODE
|
||||
// Destroy libsigrokdecode
|
||||
srd_exit();
|
||||
#endif
|
||||
|
||||
} while (0);
|
||||
|
||||
// Destroy libsigrok
|
||||
if (sr_ctx)
|
||||
sr_exit(sr_ctx);
|
||||
|
||||
return ret;
|
||||
}
|
279
DSLogic-gui/test/stylesheet.qss
Normal file
279
DSLogic-gui/test/stylesheet.qss
Normal file
@ -0,0 +1,279 @@
|
||||
palette {
|
||||
background: rgb(17, 133, 209, 255);
|
||||
disabled: rgb(200, 200, 200, 255);
|
||||
}
|
||||
|
||||
QMainWindow {
|
||||
icon-size: 48px, 48px;
|
||||
}
|
||||
|
||||
QDialog {
|
||||
border: none;
|
||||
background: rgb(17, 133, 209, 255);
|
||||
}
|
||||
|
||||
QToolBar {
|
||||
border: none;
|
||||
/*background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
|
||||
stop: 0 rgb(0, 75, 165, 255),
|
||||
stop: 0.05 rgb(31, 164, 227, 255),
|
||||
stop: 0.5 rgb(17, 133, 209, 255),
|
||||
stop: 0.95 rgb(0, 102, 185, 255),
|
||||
stop: 1 rgb(0, 75, 165, 255));*/
|
||||
background: rgb(17, 133, 209, 255);
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
pv--view--View,
|
||||
pv--view--Viewport{
|
||||
margin: 0px;
|
||||
border: none;
|
||||
background-color: rgb(255, 255, 255);
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
QToolButton {
|
||||
border: none;
|
||||
border-style: flat;
|
||||
color: white;
|
||||
font: bold 10ft;
|
||||
min-height: 50px;
|
||||
min-width: 50px;
|
||||
}
|
||||
|
||||
QPushButton:hover,
|
||||
QToolButton:hover {
|
||||
background-color: rgb(238, 178, 17, 200);
|
||||
}
|
||||
|
||||
QPushButton:pressed,
|
||||
QToolButton:pressed {
|
||||
background-color: rgb(238, 178, 17, 255);
|
||||
}
|
||||
|
||||
QPushButton {
|
||||
padding: 3px;
|
||||
border: none;
|
||||
border-style: flat;
|
||||
border-radius: 4px;
|
||||
color: white;
|
||||
background-color: rgb(255, 255, 255, 50);
|
||||
font: bold 10ft;
|
||||
min-height: 20px;
|
||||
min-width: 20px;
|
||||
}
|
||||
|
||||
/* >>> QToolBar: QLineEdit/QComboBox */
|
||||
QLineEdit,
|
||||
QComboBox:!editable,
|
||||
QSpinBox {
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
background-color: white;
|
||||
padding: 3px;
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
QLineEdit:disabled,
|
||||
QComboBox:disabled,
|
||||
QSpinBox:disabled {
|
||||
background-color: rgb(200, 200, 200, 255);
|
||||
}
|
||||
|
||||
QComboBox:!editable {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
/* QComboBox gets the "on" state when the popup is open */
|
||||
QComboBox:!editable:on, QToolBar > QComboBox::drop-down:editable:on {
|
||||
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
|
||||
stop: 0 #D3D3D3, stop: 0.4 #D8D8D8,
|
||||
stop: 0.5 #DDDDDD, stop: 1.0 #E1E1E1);
|
||||
}
|
||||
|
||||
QComboBox:on { /* shift the text when the popup opens */
|
||||
padding-top: 3px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
QComboBox::drop-down {
|
||||
subcontrol-origin: padding;
|
||||
subcontrol-position: top right;
|
||||
width: 20px;
|
||||
|
||||
border-left-width: 0px;
|
||||
border-top-right-radius: 4px; /* same radius as the QComboBox */
|
||||
border-bottom-right-radius: 4px;
|
||||
}
|
||||
|
||||
QComboBox::down-arrow {
|
||||
image: url(:/icons/down-arrow.png);
|
||||
}
|
||||
QComboBox::down-arrow:disabled {
|
||||
image: none;
|
||||
}
|
||||
|
||||
QComboBox::down-arrow:on { /* shift the arrow when popup is open */
|
||||
top: 1px;
|
||||
left: 1px;
|
||||
}
|
||||
/* <<< QToolBar: QLineEdit/QComboBox */
|
||||
|
||||
/* >>> QDockWidget */
|
||||
QDockWidget {
|
||||
margin: 0px;
|
||||
background-color: rgb(17, 133, 209, 255);
|
||||
border: 0px;
|
||||
padding: 0px;
|
||||
color: rgb(17, 133, 209, 255);
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
QDockWidget::title {
|
||||
margin: 0px;
|
||||
text-align: left center;
|
||||
background-color: rgb(255, 255, 255, 255);
|
||||
border: 0px;
|
||||
color: white;
|
||||
padding: 8px;
|
||||
}
|
||||
QDockWidget > QWidget{
|
||||
margin: 0px;
|
||||
background-color: rgb(17, 133, 209, 255);
|
||||
border: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
QGroupBox {
|
||||
margin: 0px;
|
||||
background-color: rgb(17, 133, 209, 255);
|
||||
border: 0px;
|
||||
padding: 40px, 10px, 10px, 10px;
|
||||
color: white;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
QGroupBox::title
|
||||
{
|
||||
subcontrol-origin: margin;
|
||||
subcontrol-position: top center;
|
||||
padding: 5 20px;
|
||||
}
|
||||
QGroupBox:disabled
|
||||
{
|
||||
color: rgb(200, 200, 200, 255);
|
||||
}
|
||||
|
||||
QDockWidget > QWidget > QTabWidget::pane{
|
||||
margin: 0px;
|
||||
background-color: rgb(17, 133, 209, 255);
|
||||
border: 1px solid rgb(255, 255, 255);
|
||||
border-right-color: rgb(17, 133, 209, 255); /* same as the pane color */
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
QDockWidget > QWidget > QTabWidget::pane:disabled{
|
||||
border: 1px solid rgb(200, 200, 200, 255);
|
||||
border-right-color: rgb(17, 133, 209, 255); /* same as the pane color */
|
||||
}
|
||||
|
||||
QDockWidget > QWidget > QTabWidget > QTabBar::tab
|
||||
{
|
||||
background: transparent;
|
||||
color: white;
|
||||
border: 2px solid rgb(238, 178, 17, 255);
|
||||
border-left-color: rgb(17, 133, 209, 255); /* same as the pane color */
|
||||
border-bottom-right-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
min-height: 8ex;
|
||||
padding: 2px;
|
||||
}
|
||||
QDockWidget > QWidget > QTabWidget > QTabBar::tab:hover
|
||||
{
|
||||
border: 3px solid rgb(238, 178, 17, 255);
|
||||
border-left-color: rgb(17, 133, 209, 255); /* same as the pane color */
|
||||
}
|
||||
QDockWidget > QWidget > QTabWidget > QTabBar::tab:selected
|
||||
{
|
||||
color: white;
|
||||
background: rgb(238, 178, 17, 255);
|
||||
border-left-color: rgb(17, 133, 209, 255); /* same as the pane color */
|
||||
}
|
||||
QDockWidget > QWidget > QTabWidget > QTabBar::tab:disabled
|
||||
{
|
||||
color: rgb(200, 200, 200, 50);
|
||||
border: 1px solid rgb(232, 232, 230, 255);
|
||||
background: transparent;
|
||||
border-left-color: rgb(17, 133, 209, 255); /* same as the pane color */
|
||||
}
|
||||
|
||||
QCheckBox,
|
||||
QRadioButton,
|
||||
QLabel {
|
||||
border: none;
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
QCheckBox::checked,
|
||||
QRadioButton::checked {
|
||||
color: black;
|
||||
}
|
||||
|
||||
QLabel,
|
||||
QCheckBox::unchecked,
|
||||
QRadioButton::unchecked {
|
||||
color: white;
|
||||
}
|
||||
|
||||
QCheckBox,
|
||||
QLabel {
|
||||
padding: 1px 1px 1px 1px;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
|
||||
QLabel:disabled {
|
||||
color: rgb(200, 200, 200, 255);
|
||||
}
|
||||
|
||||
QSlider::groove:horizontal {
|
||||
border: 1px solid #999999;
|
||||
height: 2px;
|
||||
margin: 0px 0;
|
||||
left: 10px; right: 10px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal {
|
||||
border-image:url(:/icons/slider-handle.png);
|
||||
margin-left: -12px;
|
||||
margin-right: -12px;
|
||||
margin-top: -11px;
|
||||
margin-bottom: -11px;
|
||||
}
|
||||
|
||||
QSlider::sub-page:horizontal{
|
||||
background: qlineargradient(spread:pad,
|
||||
x1:0, y1:1, x2:0, y2:0,
|
||||
stop:0 rgba(17, 133, 209, 255),
|
||||
stop:0.25 rgba(238, 178, 17, 255),
|
||||
stop:0.75 rgba(238, 178, 17, 255),
|
||||
stop:1 rgba(17, 133, 209, 255));
|
||||
height: 2px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
QSlider::add-page:horizontal{
|
||||
background: qlineargradient(spread:pad,
|
||||
x1:0, y1:1, x2:0, y2:0,
|
||||
stop:0 rgba(17, 133, 209, 255),
|
||||
stop:0.25 rgba(255, 255, 255, 255),
|
||||
stop:0.75 rgba(255, 255, 255, 255),
|
||||
stop:1 rgba(17, 133, 209, 255));
|
||||
height: 2px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* <<< QDockWidget */
|
File diff suppressed because it is too large
Load Diff
200
INSTALL
200
INSTALL
@ -1,100 +1,100 @@
|
||||
-------------------------------------------------------------------------------
|
||||
INSTALL
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
libsigrok4DSLoigc
|
||||
- gcc (>= 4.0)
|
||||
- make
|
||||
- autoconf >= 2.63
|
||||
- automake >= 1.11
|
||||
- libtool
|
||||
- pkg-config >= 0.22
|
||||
This is part of the standard OpenBSD install (not an extra package), apparently.
|
||||
- libglib >= 2.32.0
|
||||
- libzip >= 0.10
|
||||
- libusb-1.0 >= 1.0.16
|
||||
On FreeBSD, this is an integral part of the FreeBSD libc, not an extra package/library.
|
||||
This is part of the standard OpenBSD install (not an extra package), apparently.
|
||||
- check >= 0.9.4 (optional, only needed to run unit tests)
|
||||
|
||||
DSLgoic-gui
|
||||
- git
|
||||
- g++
|
||||
- make
|
||||
- libtool
|
||||
- pkg-config >= 0.22
|
||||
- cmake >= 2.6
|
||||
- libglib >= 2.28.0
|
||||
- Qt >= 4.5
|
||||
- libboost >= 1.42 (including the following libs):
|
||||
- libboost-system
|
||||
- libboost-thread
|
||||
- libsigrok4DSLogic >= 0.2.0
|
||||
|
||||
Building and installing
|
||||
-----------------------
|
||||
Get the DSLogic source code from: www.dreamsourcelab.com/download.html
|
||||
|
||||
|
||||
|
||||
Step1: Build libusbx-1.0.18
|
||||
Building:
|
||||
|
||||
$ cd libusbx-1.0.18
|
||||
$ ./configure
|
||||
$ make
|
||||
$ sudo make install
|
||||
|
||||
|
||||
|
||||
Step2: Build libsigrok4DSLogic
|
||||
|
||||
Installing the requirements:
|
||||
|
||||
Example on Debian/Ubuntu (please check your respective distro's package manager tool if you use other distros):
|
||||
$ sudo apt-get install git-core gcc make autoconf automake libtool pkg-config \
|
||||
libglib2.0-dev libzip-dev libudev-dev libasound2-dev check
|
||||
|
||||
Fedora (18, 19):
|
||||
$ sudo yum install git gcc make autoconf automake libtool pkgconfig glib2-devel \
|
||||
libzip-devel libudev-devel alsa-lib-devel check
|
||||
|
||||
OpenSuSE (12.2):
|
||||
$ zypper install git gcc make autoconf automake libtool pkg-config glib2-devel \
|
||||
libzip-devel libudev-devel alsa-devel check
|
||||
|
||||
Building:
|
||||
|
||||
$ cd libsigrok4DSLogic
|
||||
$ ./autogen.sh
|
||||
$ ./configure
|
||||
$ make
|
||||
$ sudo make install
|
||||
|
||||
|
||||
|
||||
Step3: Build DSLogic-gui
|
||||
|
||||
Installing the requirements:
|
||||
|
||||
Example on Debian/Ubuntu (please check your respective distro's package manager tool if you use other distros):
|
||||
$ sudo apt-get install git-core g++ make cmake libtool pkg-config \
|
||||
libglib2.0-dev libqt4-dev libboost-dev libboost-test-dev libboost-thread-dev libboost-system-dev
|
||||
|
||||
Fedora (18, 19):
|
||||
$ sudo yum install git gcc cmake libtool pkgconfig glib2-devel \
|
||||
boost-devel qt-devel boost-devel
|
||||
|
||||
Building:
|
||||
|
||||
$ cd DSLogic-gui
|
||||
$ cmake .
|
||||
$ make
|
||||
$ sudo make install
|
||||
|
||||
See the following wiki page for more (OS-specific) instructions:
|
||||
|
||||
http://sigrok.org/wiki/Building
|
||||
-------------------------------------------------------------------------------
|
||||
INSTALL
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
libsigrok4DSLoigc
|
||||
- gcc (>= 4.0)
|
||||
- make
|
||||
- autoconf >= 2.63
|
||||
- automake >= 1.11
|
||||
- libtool
|
||||
- pkg-config >= 0.22
|
||||
This is part of the standard OpenBSD install (not an extra package), apparently.
|
||||
- libglib >= 2.32.0
|
||||
- libzip >= 0.10
|
||||
- libusb-1.0 >= 1.0.16
|
||||
On FreeBSD, this is an integral part of the FreeBSD libc, not an extra package/library.
|
||||
This is part of the standard OpenBSD install (not an extra package), apparently.
|
||||
- check >= 0.9.4 (optional, only needed to run unit tests)
|
||||
|
||||
DSLgoic-gui
|
||||
- git
|
||||
- g++
|
||||
- make
|
||||
- libtool
|
||||
- pkg-config >= 0.22
|
||||
- cmake >= 2.6
|
||||
- libglib >= 2.28.0
|
||||
- Qt >= 4.5
|
||||
- libboost >= 1.42 (including the following libs):
|
||||
- libboost-system
|
||||
- libboost-thread
|
||||
- libsigrok4DSLogic >= 0.2.0
|
||||
|
||||
Building and installing
|
||||
-----------------------
|
||||
Get the DSLogic source code from: www.dreamsourcelab.com/download.html
|
||||
|
||||
|
||||
|
||||
Step1: Build libusbx-1.0.18
|
||||
Building:
|
||||
|
||||
$ cd libusbx-1.0.18
|
||||
$ ./configure
|
||||
$ make
|
||||
$ sudo make install
|
||||
|
||||
|
||||
|
||||
Step2: Build libsigrok4DSLogic
|
||||
|
||||
Installing the requirements:
|
||||
|
||||
Example on Debian/Ubuntu (please check your respective distro's package manager tool if you use other distros):
|
||||
$ sudo apt-get install git-core gcc make autoconf automake libtool pkg-config \
|
||||
libglib2.0-dev libzip-dev libudev-dev libasound2-dev check
|
||||
|
||||
Fedora (18, 19):
|
||||
$ sudo yum install git gcc make autoconf automake libtool pkgconfig glib2-devel \
|
||||
libzip-devel libudev-devel alsa-lib-devel check
|
||||
|
||||
OpenSuSE (12.2):
|
||||
$ zypper install git gcc make autoconf automake libtool pkg-config glib2-devel \
|
||||
libzip-devel libudev-devel alsa-devel check
|
||||
|
||||
Building:
|
||||
|
||||
$ cd libsigrok4DSLogic
|
||||
$ ./autogen.sh
|
||||
$ ./configure
|
||||
$ make
|
||||
$ sudo make install
|
||||
|
||||
|
||||
|
||||
Step3: Build DSLogic-gui
|
||||
|
||||
Installing the requirements:
|
||||
|
||||
Example on Debian/Ubuntu (please check your respective distro's package manager tool if you use other distros):
|
||||
$ sudo apt-get install git-core g++ make cmake libtool pkg-config \
|
||||
libglib2.0-dev libqt4-dev libboost-dev libboost-test-dev libboost-thread-dev libboost-system-dev
|
||||
|
||||
Fedora (18, 19):
|
||||
$ sudo yum install git gcc cmake libtool pkgconfig glib2-devel \
|
||||
boost-devel qt-devel boost-devel
|
||||
|
||||
Building:
|
||||
|
||||
$ cd DSLogic-gui
|
||||
$ cmake .
|
||||
$ make
|
||||
$ sudo make install
|
||||
|
||||
See the following wiki page for more (OS-specific) instructions:
|
||||
|
||||
http://sigrok.org/wiki/Building
|
||||
|
48
NEWS
48
NEWS
@ -1,18 +1,30 @@
|
||||
0.1.0 (2013-12-15)
|
||||
------------------
|
||||
|
||||
* Initial release.
|
||||
|
||||
|
||||
0.2.0 (2014-04-13)
|
||||
------------------
|
||||
|
||||
* Add DSLogic hardware support.
|
||||
0.2.1 (2014-05-08)
|
||||
------------------
|
||||
|
||||
* Add wireless extension hardware support.
|
||||
* Fix libusb_error_io issue on Linux when sample rate >= 100MHz.
|
||||
* Fix channel enable/disable bug.
|
||||
* Fix device options config issue.
|
||||
* Fix some display issues of UI.
|
||||
0.1.0 (2013-12-15)
|
||||
------------------
|
||||
|
||||
* Initial release.
|
||||
|
||||
0.2.0 (2014-04-13)
|
||||
------------------
|
||||
|
||||
* Add DSLogic hardware support.
|
||||
|
||||
0.2.1 (2014-05-08)
|
||||
------------------
|
||||
|
||||
* Add wireless extension hardware support.
|
||||
* Fix libusb_error_io issue on Linux when sample rate >= 100MHz.
|
||||
* Fix channel enable/disable bug.
|
||||
* Fix device options config issue.
|
||||
* Fix some display issues of UI.
|
||||
|
||||
0.3 (2014-06-29)
|
||||
-----------------
|
||||
* Add DSLogic Oscilloscope module support.
|
||||
* Fix data display issue when not all channels be enabled.
|
||||
* Fix issue of data mirrored to other channels.
|
||||
* Fix radiobutton/checkbox display issue under certain windows theme.
|
||||
* Add new simple trigger type
|
||||
* Fix bugs of trigger setting and detection
|
||||
* Fix other minior issues.
|
||||
* Clean up the git repository
|
||||
|
||||
|
114
README
114
README
@ -1,57 +1,57 @@
|
||||
-------------------------------------------------------------------------------
|
||||
README
|
||||
-------------------------------------------------------------------------------
|
||||
DSLogic is an open source multi-function instrument for everyone.
|
||||
DSLogic software is based on sigrok project.
|
||||
You can find DSLogic on:
|
||||
www.dreamsourcelab.com
|
||||
www.kickstarter.com/projects/dreamsourcelab/dslogic-multifunction-instruments-for-everyone
|
||||
|
||||
The sigrok project aims at creating a portable, cross-platform,
|
||||
Free/Libre/Open-Source signal analysis software suite that supports various
|
||||
device types (such as logic analyzers, oscilloscopes, multimeters, and more).
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
DSLogic software is in a usable state and has had official tarball releases.
|
||||
|
||||
However, it is still work in progress. Some basic functionality
|
||||
is available and working, but other things are still on the TODO list.
|
||||
|
||||
|
||||
Copyright and license
|
||||
---------------------
|
||||
|
||||
DSLogic software is licensed under the terms of the GNU General Public License
|
||||
(GPL), version 3 or later.
|
||||
|
||||
While some individual source code files are licensed under the GPLv2+, and
|
||||
some files are licensed under the GPLv3+, this doesn't change the fact that
|
||||
the program as a whole is licensed under the terms of the GPLv3+ (e.g. also
|
||||
due to the fact that it links against GPLv3+ libraries).
|
||||
|
||||
Please see the individual source files for the full list of copyright holders.
|
||||
|
||||
|
||||
Copyright notices
|
||||
-----------------
|
||||
|
||||
A copyright notice indicating a range of years, must be interpreted as having
|
||||
had copyrightable material added in each of those years.
|
||||
|
||||
Example:
|
||||
|
||||
Copyright (C) 2010-2013 Contributor Name
|
||||
|
||||
is to be interpreted as
|
||||
|
||||
Copyright (C) 2010,2011,2012,2013 Contributor Name
|
||||
|
||||
|
||||
Website
|
||||
-------
|
||||
http://dreamsourcelab.com
|
||||
http://sigrok.org
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
README
|
||||
-------------------------------------------------------------------------------
|
||||
DSLogic is an open source multi-function instrument for everyone.
|
||||
DSLogic software is based on sigrok project.
|
||||
You can find DSLogic on:
|
||||
www.dreamsourcelab.com
|
||||
www.kickstarter.com/projects/dreamsourcelab/dslogic-multifunction-instruments-for-everyone
|
||||
|
||||
The sigrok project aims at creating a portable, cross-platform,
|
||||
Free/Libre/Open-Source signal analysis software suite that supports various
|
||||
device types (such as logic analyzers, oscilloscopes, multimeters, and more).
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
DSLogic software is in a usable state and has had official tarball releases.
|
||||
|
||||
However, it is still work in progress. Some basic functionality
|
||||
is available and working, but other things are still on the TODO list.
|
||||
|
||||
|
||||
Copyright and license
|
||||
---------------------
|
||||
|
||||
DSLogic software is licensed under the terms of the GNU General Public License
|
||||
(GPL), version 3 or later.
|
||||
|
||||
While some individual source code files are licensed under the GPLv2+, and
|
||||
some files are licensed under the GPLv3+, this doesn't change the fact that
|
||||
the program as a whole is licensed under the terms of the GPLv3+ (e.g. also
|
||||
due to the fact that it links against GPLv3+ libraries).
|
||||
|
||||
Please see the individual source files for the full list of copyright holders.
|
||||
|
||||
|
||||
Copyright notices
|
||||
-----------------
|
||||
|
||||
A copyright notice indicating a range of years, must be interpreted as having
|
||||
had copyrightable material added in each of those years.
|
||||
|
||||
Example:
|
||||
|
||||
Copyright (C) 2010-2013 Contributor Name
|
||||
|
||||
is to be interpreted as
|
||||
|
||||
Copyright (C) 2010,2011,2012,2013 Contributor Name
|
||||
|
||||
|
||||
Website
|
||||
-------
|
||||
http://dreamsourcelab.com
|
||||
http://sigrok.org
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,177 +1,208 @@
|
||||
/*
|
||||
* This file is part of the libsigrok project.
|
||||
*
|
||||
* Copyright (C) 2013 Bert Vermeulen <bert@biot.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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <libusb.h>
|
||||
#include "command.h"
|
||||
//#include "libsigrok.h"
|
||||
#include "libsigrok-internal.h"
|
||||
#include "dslogic.h"
|
||||
|
||||
SR_PRIV int command_get_fw_version(libusb_device_handle *devhdl,
|
||||
struct version_info *vi)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR |
|
||||
LIBUSB_ENDPOINT_IN, CMD_GET_FW_VERSION, 0x0000, 0x0000,
|
||||
(unsigned char *)vi, sizeof(struct version_info), 100);
|
||||
|
||||
if (ret < 0) {
|
||||
sr_err("Unable to get version info: %s.",
|
||||
libusb_error_name(ret));
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
SR_PRIV int command_get_revid_version(libusb_device_handle *devhdl,
|
||||
uint8_t *revid)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR |
|
||||
LIBUSB_ENDPOINT_IN, CMD_GET_REVID_VERSION, 0x0000, 0x0000,
|
||||
revid, 1, 100);
|
||||
|
||||
if (ret < 0) {
|
||||
sr_err("Unable to get REVID: %s.", libusb_error_name(ret));
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
SR_PRIV int command_start_acquisition(libusb_device_handle *devhdl,
|
||||
uint64_t samplerate, gboolean samplewide)
|
||||
{
|
||||
struct cmd_start_acquisition cmd;
|
||||
int delay = 0, ret;
|
||||
|
||||
/* Compute the sample rate. */
|
||||
// if (samplewide && samplerate > MAX_16BIT_SAMPLE_RATE) {
|
||||
// sr_err("Unable to sample at %" PRIu64 "Hz "
|
||||
// "when collecting 16-bit samples.", samplerate);
|
||||
// return SR_ERR;
|
||||
// }
|
||||
|
||||
// if ((SR_MHZ(48) % samplerate) == 0) {
|
||||
// cmd.flags = CMD_START_FLAGS_CLK_48MHZ;
|
||||
// delay = SR_MHZ(48) / samplerate - 1;
|
||||
// if (delay > MAX_SAMPLE_DELAY)
|
||||
// delay = 0;
|
||||
// }
|
||||
|
||||
// if (delay == 0 && (SR_MHZ(30) % samplerate) == 0) {
|
||||
// cmd.flags = CMD_START_FLAGS_CLK_30MHZ;
|
||||
// delay = SR_MHZ(30) / samplerate - 1;
|
||||
// }
|
||||
cmd.flags = CMD_START_FLAGS_CLK_30MHZ;
|
||||
delay = 0;
|
||||
|
||||
sr_info("GPIF delay = %d, clocksource = %sMHz.", delay,
|
||||
(cmd.flags & CMD_START_FLAGS_CLK_48MHZ) ? "48" : "30");
|
||||
|
||||
// if (delay <= 0 || delay > MAX_SAMPLE_DELAY) {
|
||||
// sr_err("Unable to sample at %" PRIu64 "Hz.", samplerate);
|
||||
// return SR_ERR;
|
||||
// }
|
||||
|
||||
cmd.sample_delay_h = (delay >> 8) & 0xff;
|
||||
cmd.sample_delay_l = delay & 0xff;
|
||||
|
||||
/* Select the sampling width. */
|
||||
cmd.flags |= samplewide ? CMD_START_FLAGS_SAMPLE_16BIT :
|
||||
CMD_START_FLAGS_SAMPLE_8BIT;
|
||||
|
||||
/* Send the control message. */
|
||||
ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR |
|
||||
LIBUSB_ENDPOINT_OUT, CMD_START, 0x0000, 0x0000,
|
||||
(unsigned char *)&cmd, sizeof(cmd), 3000);
|
||||
if (ret < 0) {
|
||||
sr_err("Unable to send start command: %s.",
|
||||
libusb_error_name(ret));
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
SR_PRIV int command_stop_acquisition(libusb_device_handle *devhdl)
|
||||
{
|
||||
struct cmd_start_acquisition cmd;
|
||||
int ret;
|
||||
|
||||
/* stop acquisition command */
|
||||
cmd.flags = CMD_START_FLAGS_STOP;
|
||||
cmd.sample_delay_h = 0;
|
||||
cmd.sample_delay_l = 0;
|
||||
|
||||
/* Send the control message. */
|
||||
ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR |
|
||||
LIBUSB_ENDPOINT_OUT, CMD_START, 0x0000, 0x0000,
|
||||
(unsigned char *)&cmd, sizeof(cmd), 3000);
|
||||
if (ret < 0) {
|
||||
sr_err("Unable to send stop command: %s.",
|
||||
libusb_error_name(ret));
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
SR_PRIV int command_fpga_config(libusb_device_handle *devhdl)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Send the control message. */
|
||||
ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR |
|
||||
LIBUSB_ENDPOINT_OUT, CMD_CONFIG, 0x0000, 0x0000,
|
||||
NULL, 0, 3000);
|
||||
if (ret < 0) {
|
||||
sr_err("Unable to send FPGA configure command: %s.",
|
||||
libusb_error_name(ret));
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
SR_PRIV int command_fpga_setting(libusb_device_handle *devhdl, uint32_t setting_count)
|
||||
{
|
||||
struct cmd_setting_count cmd;
|
||||
int ret;
|
||||
|
||||
/* ... */
|
||||
cmd.byte0 = (uint8_t)setting_count;
|
||||
cmd.byte1 = (uint8_t)(setting_count >> 8);
|
||||
cmd.byte2 = (uint8_t)(setting_count >> 16);
|
||||
|
||||
/* Send the control message. */
|
||||
ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR |
|
||||
LIBUSB_ENDPOINT_OUT, CMD_SETTING, 0x0000, 0x0000,
|
||||
(unsigned char *)&cmd, sizeof(cmd), 100);
|
||||
if (ret < 0) {
|
||||
sr_err("Unable to send FPGA setting command: %s.",
|
||||
libusb_error_name(ret));
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
/*
|
||||
* This file is part of the libsigrok project.
|
||||
*
|
||||
* Copyright (C) 2013 Bert Vermeulen <bert@biot.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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <libusb.h>
|
||||
#include "command.h"
|
||||
//#include "libsigrok.h"
|
||||
#include "libsigrok-internal.h"
|
||||
#include "dslogic.h"
|
||||
|
||||
SR_PRIV int command_get_fw_version(libusb_device_handle *devhdl,
|
||||
struct version_info *vi)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR |
|
||||
LIBUSB_ENDPOINT_IN, CMD_GET_FW_VERSION, 0x0000, 0x0000,
|
||||
(unsigned char *)vi, sizeof(struct version_info), 100);
|
||||
|
||||
if (ret < 0) {
|
||||
sr_err("Unable to get version info: %s.",
|
||||
libusb_error_name(ret));
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
SR_PRIV int command_get_revid_version(libusb_device_handle *devhdl,
|
||||
uint8_t *revid)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR |
|
||||
LIBUSB_ENDPOINT_IN, CMD_GET_REVID_VERSION, 0x0000, 0x0000,
|
||||
revid, 1, 100);
|
||||
|
||||
if (ret < 0) {
|
||||
sr_err("Unable to get REVID: %s.", libusb_error_name(ret));
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
SR_PRIV int command_start_acquisition(libusb_device_handle *devhdl,
|
||||
uint64_t samplerate, gboolean samplewide)
|
||||
{
|
||||
struct cmd_start_acquisition cmd;
|
||||
int delay = 0, ret;
|
||||
|
||||
/* Compute the sample rate. */
|
||||
// if (samplewide && samplerate > MAX_16BIT_SAMPLE_RATE) {
|
||||
// sr_err("Unable to sample at %" PRIu64 "Hz "
|
||||
// "when collecting 16-bit samples.", samplerate);
|
||||
// return SR_ERR;
|
||||
// }
|
||||
|
||||
// if ((SR_MHZ(48) % samplerate) == 0) {
|
||||
// cmd.flags = CMD_START_FLAGS_CLK_48MHZ;
|
||||
// delay = SR_MHZ(48) / samplerate - 1;
|
||||
// if (delay > MAX_SAMPLE_DELAY)
|
||||
// delay = 0;
|
||||
// }
|
||||
|
||||
// if (delay == 0 && (SR_MHZ(30) % samplerate) == 0) {
|
||||
// cmd.flags = CMD_START_FLAGS_CLK_30MHZ;
|
||||
// delay = SR_MHZ(30) / samplerate - 1;
|
||||
// }
|
||||
cmd.flags = CMD_START_FLAGS_CLK_30MHZ;
|
||||
delay = 0;
|
||||
|
||||
sr_info("GPIF delay = %d, clocksource = %sMHz.", delay,
|
||||
(cmd.flags & CMD_START_FLAGS_CLK_48MHZ) ? "48" : "30");
|
||||
|
||||
// if (delay <= 0 || delay > MAX_SAMPLE_DELAY) {
|
||||
// sr_err("Unable to sample at %" PRIu64 "Hz.", samplerate);
|
||||
// return SR_ERR;
|
||||
// }
|
||||
|
||||
cmd.sample_delay_h = (delay >> 8) & 0xff;
|
||||
cmd.sample_delay_l = delay & 0xff;
|
||||
|
||||
/* Select the sampling width. */
|
||||
cmd.flags |= samplewide ? CMD_START_FLAGS_SAMPLE_16BIT :
|
||||
CMD_START_FLAGS_SAMPLE_8BIT;
|
||||
|
||||
/* Send the control message. */
|
||||
ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR |
|
||||
LIBUSB_ENDPOINT_OUT, CMD_START, 0x0000, 0x0000,
|
||||
(unsigned char *)&cmd, sizeof(cmd), 3000);
|
||||
if (ret < 0) {
|
||||
sr_err("Unable to send start command: %s.",
|
||||
libusb_error_name(ret));
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
SR_PRIV int command_stop_acquisition(libusb_device_handle *devhdl)
|
||||
{
|
||||
struct cmd_start_acquisition cmd;
|
||||
int ret;
|
||||
|
||||
/* stop acquisition command */
|
||||
cmd.flags = CMD_START_FLAGS_STOP;
|
||||
cmd.sample_delay_h = 0;
|
||||
cmd.sample_delay_l = 0;
|
||||
|
||||
/* Send the control message. */
|
||||
ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR |
|
||||
LIBUSB_ENDPOINT_OUT, CMD_START, 0x0000, 0x0000,
|
||||
(unsigned char *)&cmd, sizeof(cmd), 3000);
|
||||
if (ret < 0) {
|
||||
sr_err("Unable to send stop command: %s.",
|
||||
libusb_error_name(ret));
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
SR_PRIV int command_fpga_config(libusb_device_handle *devhdl)
|
||||
{
|
||||
struct cmd_cfg_count cmd;
|
||||
int ret;
|
||||
|
||||
/* ... */
|
||||
cmd.byte0 = (uint8_t)XC6SLX9_BYTE_CNT;
|
||||
cmd.byte1 = (uint8_t)(XC6SLX9_BYTE_CNT >> 8);
|
||||
cmd.byte2 = (uint8_t)(XC6SLX9_BYTE_CNT >> 16);
|
||||
|
||||
/* Send the control message. */
|
||||
ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR |
|
||||
LIBUSB_ENDPOINT_OUT, CMD_CONFIG, 0x0000, 0x0000,
|
||||
(unsigned char *)&cmd, sizeof(cmd), 3000);
|
||||
if (ret < 0) {
|
||||
sr_err("Unable to send FPGA configure command: %s.",
|
||||
libusb_error_name(ret));
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
SR_PRIV int command_fpga_setting(libusb_device_handle *devhdl, uint32_t setting_count)
|
||||
{
|
||||
struct cmd_setting_count cmd;
|
||||
int ret;
|
||||
|
||||
/* ... */
|
||||
cmd.byte0 = (uint8_t)setting_count;
|
||||
cmd.byte1 = (uint8_t)(setting_count >> 8);
|
||||
cmd.byte2 = (uint8_t)(setting_count >> 16);
|
||||
|
||||
/* Send the control message. */
|
||||
ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR |
|
||||
LIBUSB_ENDPOINT_OUT, CMD_SETTING, 0x0000, 0x0000,
|
||||
(unsigned char *)&cmd, sizeof(cmd), 3000);
|
||||
if (ret < 0) {
|
||||
sr_err("Unable to send FPGA setting command: %s.",
|
||||
libusb_error_name(ret));
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
SR_PRIV int command_dso_ctrl(libusb_device_handle *devhdl, uint32_t command)
|
||||
{
|
||||
struct cmd_control cmd;
|
||||
int ret;
|
||||
|
||||
/* ... */
|
||||
cmd.byte0 = (uint8_t)command;
|
||||
cmd.byte1 = (uint8_t)(command >> 8);
|
||||
cmd.byte2 = (uint8_t)(command >> 16);
|
||||
cmd.byte3 = (uint8_t)(command >> 24);
|
||||
|
||||
|
||||
/* Send the control command. */
|
||||
ret = libusb_control_transfer(devhdl, LIBUSB_REQUEST_TYPE_VENDOR |
|
||||
LIBUSB_ENDPOINT_OUT, CMD_CONTROL, 0x0000, 0x0000,
|
||||
(unsigned char *)&cmd, sizeof(cmd), 3000);
|
||||
if (ret < 0) {
|
||||
sr_err("Unable to send oscilloscope control command: %s.",
|
||||
libusb_error_name(ret));
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
@ -1,79 +1,93 @@
|
||||
/*
|
||||
* This file is part of the libsigrok project.
|
||||
*
|
||||
* Copyright (C) 2013 Bert Vermeulen <bert@biot.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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LIBDSLOGIC_HARDWARE_COMMAND_H
|
||||
#define LIBDSLOGIC_HARDWARE_COMMAND_H
|
||||
|
||||
#include <glib.h>
|
||||
#include "libsigrok.h"
|
||||
|
||||
/* Protocol commands */
|
||||
#define CMD_GET_FW_VERSION 0xb0
|
||||
#define CMD_GET_REVID_VERSION 0xb1
|
||||
#define CMD_START 0xb2
|
||||
#define CMD_CONFIG 0xb3
|
||||
#define CMD_SETTING 0xb4
|
||||
|
||||
|
||||
#define CMD_START_FLAGS_WIDE_POS 5
|
||||
#define CMD_START_FLAGS_CLK_SRC_POS 6
|
||||
#define CMD_START_FLAGS_STOP_POS 7
|
||||
|
||||
#define CMD_START_FLAGS_SAMPLE_8BIT (0 << CMD_START_FLAGS_WIDE_POS)
|
||||
#define CMD_START_FLAGS_SAMPLE_16BIT (1 << CMD_START_FLAGS_WIDE_POS)
|
||||
|
||||
#define CMD_START_FLAGS_CLK_30MHZ (0 << CMD_START_FLAGS_CLK_SRC_POS)
|
||||
#define CMD_START_FLAGS_CLK_48MHZ (1 << CMD_START_FLAGS_CLK_SRC_POS)
|
||||
|
||||
#define CMD_START_FLAGS_STOP (1 << CMD_START_FLAGS_STOP_POS)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct version_info {
|
||||
uint8_t major;
|
||||
uint8_t minor;
|
||||
};
|
||||
|
||||
struct cmd_start_acquisition {
|
||||
uint8_t flags;
|
||||
uint8_t sample_delay_h;
|
||||
uint8_t sample_delay_l;
|
||||
};
|
||||
|
||||
struct cmd_setting_count {
|
||||
uint8_t byte0;
|
||||
uint8_t byte1;
|
||||
uint8_t byte2;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
SR_PRIV int command_get_fw_version(libusb_device_handle *devhdl,
|
||||
struct version_info *vi);
|
||||
SR_PRIV int command_get_revid_version(libusb_device_handle *devhdl,
|
||||
uint8_t *revid);
|
||||
SR_PRIV int command_start_acquisition(libusb_device_handle *devhdl,
|
||||
uint64_t samplerate, gboolean samplewide);
|
||||
SR_PRIV int command_stop_acquistition(libusb_device_handle *devhdl);
|
||||
|
||||
SR_PRIV int command_fpga_config(libusb_device_handle *devhdl);
|
||||
|
||||
SR_PRIV int command_fpga_setting(libusb_device_handle *devhdl, uint32_t setting_count);
|
||||
|
||||
#endif
|
||||
/*
|
||||
* This file is part of the libsigrok project.
|
||||
*
|
||||
* Copyright (C) 2013 Bert Vermeulen <bert@biot.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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LIBDSLOGIC_HARDWARE_COMMAND_H
|
||||
#define LIBDSLOGIC_HARDWARE_COMMAND_H
|
||||
|
||||
#include <glib.h>
|
||||
#include "libsigrok.h"
|
||||
|
||||
/* Protocol commands */
|
||||
#define CMD_GET_FW_VERSION 0xb0
|
||||
#define CMD_GET_REVID_VERSION 0xb1
|
||||
#define CMD_START 0xb2
|
||||
#define CMD_CONFIG 0xb3
|
||||
#define CMD_SETTING 0xb4
|
||||
#define CMD_CONTROL 0xb5
|
||||
|
||||
#define CMD_START_FLAGS_WIDE_POS 5
|
||||
#define CMD_START_FLAGS_CLK_SRC_POS 6
|
||||
#define CMD_START_FLAGS_STOP_POS 7
|
||||
|
||||
#define CMD_START_FLAGS_SAMPLE_8BIT (0 << CMD_START_FLAGS_WIDE_POS)
|
||||
#define CMD_START_FLAGS_SAMPLE_16BIT (1 << CMD_START_FLAGS_WIDE_POS)
|
||||
|
||||
#define CMD_START_FLAGS_CLK_30MHZ (0 << CMD_START_FLAGS_CLK_SRC_POS)
|
||||
#define CMD_START_FLAGS_CLK_48MHZ (1 << CMD_START_FLAGS_CLK_SRC_POS)
|
||||
|
||||
#define CMD_START_FLAGS_STOP (1 << CMD_START_FLAGS_STOP_POS)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct version_info {
|
||||
uint8_t major;
|
||||
uint8_t minor;
|
||||
};
|
||||
|
||||
struct cmd_start_acquisition {
|
||||
uint8_t flags;
|
||||
uint8_t sample_delay_h;
|
||||
uint8_t sample_delay_l;
|
||||
};
|
||||
|
||||
struct cmd_setting_count {
|
||||
uint8_t byte0;
|
||||
uint8_t byte1;
|
||||
uint8_t byte2;
|
||||
};
|
||||
|
||||
struct cmd_cfg_count {
|
||||
uint8_t byte0;
|
||||
uint8_t byte1;
|
||||
uint8_t byte2;
|
||||
};
|
||||
|
||||
struct cmd_control {
|
||||
uint8_t byte0;
|
||||
uint8_t byte1;
|
||||
uint8_t byte2;
|
||||
uint8_t byte3;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
SR_PRIV int command_get_fw_version(libusb_device_handle *devhdl,
|
||||
struct version_info *vi);
|
||||
SR_PRIV int command_get_revid_version(libusb_device_handle *devhdl,
|
||||
uint8_t *revid);
|
||||
SR_PRIV int command_start_acquisition(libusb_device_handle *devhdl,
|
||||
uint64_t samplerate, gboolean samplewide);
|
||||
SR_PRIV int command_stop_acquistition(libusb_device_handle *devhdl);
|
||||
|
||||
SR_PRIV int command_fpga_config(libusb_device_handle *devhdl);
|
||||
SR_PRIV int command_fpga_setting(libusb_device_handle *devhdl, uint32_t setting_count);
|
||||
|
||||
SR_PRIV int command_dso_ctrl(libusb_device_handle *devhdl, uint32_t command);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,196 +1,212 @@
|
||||
/*
|
||||
* This file is part of the libsigrok project.
|
||||
*
|
||||
* Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LIBDSLOGIC_HARDWARE_DSLOGIC_H
|
||||
#define LIBDSLOGIC_HARDWARE_DSLOGIC_H
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
/* Message logging helpers with subsystem-specific prefix string. */
|
||||
#define LOG_PREFIX "DSLogic Hardware: "
|
||||
#define ds_log(l, s, args...) ds_log(l, LOG_PREFIX s, ## args)
|
||||
#define ds_spew(s, args...) ds_spew(LOG_PREFIX s, ## args)
|
||||
#define ds_dbg(s, args...) ds_dbg(LOG_PREFIX s, ## args)
|
||||
#define ds_info(s, args...) ds_info(LOG_PREFIX s, ## args)
|
||||
#define ds_warn(s, args...) ds_warn(LOG_PREFIX s, ## args)
|
||||
#define ds_err(s, args...) ds_err(LOG_PREFIX s, ## args)
|
||||
|
||||
#define USB_INTERFACE 0
|
||||
#define USB_CONFIGURATION 1
|
||||
#define NUM_TRIGGER_STAGES 16
|
||||
#define TRIGGER_TYPE "01"
|
||||
|
||||
#define MAX_RENUM_DELAY_MS 3000
|
||||
#define NUM_SIMUL_TRANSFERS 64
|
||||
#define MAX_EMPTY_TRANSFERS (NUM_SIMUL_TRANSFERS * 2)
|
||||
|
||||
#define DSLOGIC_REQUIRED_VERSION_MAJOR 1
|
||||
|
||||
#define MAX_8BIT_SAMPLE_RATE DS_MHZ(24)
|
||||
#define MAX_16BIT_SAMPLE_RATE DS_MHZ(12)
|
||||
|
||||
/* 6 delay states of up to 256 clock ticks */
|
||||
#define MAX_SAMPLE_DELAY (6 * 256)
|
||||
|
||||
/* Software trigger implementation: positive values indicate trigger stage. */
|
||||
#define TRIGGER_FIRED -1
|
||||
|
||||
#define DEV_CAPS_16BIT_POS 0
|
||||
|
||||
#define DEV_CAPS_16BIT (1 << DEV_CAPS_16BIT_POS)
|
||||
|
||||
#define XC3S250E_BYTE_CNT 169216
|
||||
//#define XC6SLX9_BYTE_CNT 340884
|
||||
#define XC6SLX9_BYTE_CNT 340604
|
||||
|
||||
#define MAX_ANALOG_PROBES_NUM 9
|
||||
#define MAX_DSO_PROBES_NUM 2
|
||||
|
||||
struct DSLogic_profile {
|
||||
uint16_t vid;
|
||||
uint16_t pid;
|
||||
|
||||
const char *vendor;
|
||||
const char *model;
|
||||
const char *model_version;
|
||||
|
||||
const char *firmware;
|
||||
|
||||
const char *fpga_bit;
|
||||
|
||||
uint32_t dev_caps;
|
||||
};
|
||||
|
||||
static const struct DSLogic_profile supported_fx2[3] = {
|
||||
/*
|
||||
* DSLogic
|
||||
*/
|
||||
{0x2A0E, 0x0001, NULL, "DSLogic", NULL,
|
||||
"DSLogic.fw",
|
||||
"DSLogic.bin",
|
||||
DEV_CAPS_16BIT},
|
||||
|
||||
{ 0, 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
enum {
|
||||
DSLOGIC_ERROR = -1,
|
||||
DSLOGIC_INIT = 0,
|
||||
DSLOGIC_START = 1,
|
||||
DSLOGIC_TRIGGERED = 2,
|
||||
DSLOGIC_DATA = 3,
|
||||
DSLOGIC_STOP = 4,
|
||||
};
|
||||
|
||||
struct dev_context {
|
||||
const struct DSLogic_profile *profile;
|
||||
/*
|
||||
* Since we can't keep track of an DSLogic device after upgrading
|
||||
* the firmware (it renumerates into a different device address
|
||||
* after the upgrade) this is like a global lock. No device will open
|
||||
* until a proper delay after the last device was upgraded.
|
||||
*/
|
||||
int64_t fw_updated;
|
||||
|
||||
/* Device/capture settings */
|
||||
uint64_t cur_samplerate;
|
||||
uint64_t limit_samples;
|
||||
|
||||
/* Operational settings */
|
||||
gboolean sample_wide;
|
||||
gboolean clock_type;
|
||||
uint16_t op_mode;
|
||||
uint16_t trigger_mask[NUM_TRIGGER_STAGES];
|
||||
uint16_t trigger_value[NUM_TRIGGER_STAGES];
|
||||
int trigger_stage;
|
||||
uint16_t trigger_buffer[NUM_TRIGGER_STAGES];
|
||||
|
||||
int num_samples;
|
||||
int submitted_transfers;
|
||||
int empty_transfer_count;
|
||||
|
||||
void *cb_data;
|
||||
unsigned int num_transfers;
|
||||
struct libusb_transfer **transfers;
|
||||
int *usbfd;
|
||||
|
||||
int status;
|
||||
};
|
||||
|
||||
struct DSLogic_setting {
|
||||
uint32_t sync;
|
||||
uint16_t mode_header; // 0
|
||||
uint16_t mode;
|
||||
uint32_t divider_header; // 1-2
|
||||
uint32_t divider;
|
||||
uint32_t count_header; // 3-4
|
||||
uint32_t count;
|
||||
uint32_t trig_pos_header; // 5-6
|
||||
uint32_t trig_pos;
|
||||
uint16_t trig_glb_header; // 7
|
||||
uint16_t trig_glb;
|
||||
uint32_t trig_adp_header; // 10-11
|
||||
uint32_t trig_adp;
|
||||
uint32_t trig_sda_header; // 12-13
|
||||
uint32_t trig_sda;
|
||||
uint32_t trig_mask0_header; // 16
|
||||
uint16_t trig_mask0[NUM_TRIGGER_STAGES];
|
||||
uint32_t trig_mask1_header; // 17
|
||||
uint16_t trig_mask1[NUM_TRIGGER_STAGES];
|
||||
//uint32_t trig_mask2_header; // 18
|
||||
//uint16_t trig_mask2[NUM_TRIGGER_STAGES];
|
||||
//uint32_t trig_mask3_header; // 19
|
||||
//uint16_t trig_mask3[NUM_TRIGGER_STAGES];
|
||||
uint32_t trig_value0_header; // 20
|
||||
uint16_t trig_value0[NUM_TRIGGER_STAGES];
|
||||
uint32_t trig_value1_header; // 21
|
||||
uint16_t trig_value1[NUM_TRIGGER_STAGES];
|
||||
//uint32_t trig_value2_header; // 22
|
||||
//uint16_t trig_value2[NUM_TRIGGER_STAGES];
|
||||
//uint32_t trig_value3_header; // 23
|
||||
//uint16_t trig_value3[NUM_TRIGGER_STAGES];
|
||||
uint32_t trig_edge0_header; // 24
|
||||
uint16_t trig_edge0[NUM_TRIGGER_STAGES];
|
||||
uint32_t trig_edge1_header; // 25
|
||||
uint16_t trig_edge1[NUM_TRIGGER_STAGES];
|
||||
//uint32_t trig_edge2_header; // 26
|
||||
//uint16_t trig_edge2[NUM_TRIGGER_STAGES];
|
||||
//uint32_t trig_edge3_header; // 27
|
||||
//uint16_t trig_edge3[NUM_TRIGGER_STAGES];
|
||||
uint32_t trig_count0_header; // 28
|
||||
uint16_t trig_count0[NUM_TRIGGER_STAGES];
|
||||
uint32_t trig_count1_header; // 29
|
||||
uint16_t trig_count1[NUM_TRIGGER_STAGES];
|
||||
//uint32_t trig_count2_header; // 30
|
||||
//uint16_t trig_count2[NUM_TRIGGER_STAGES];
|
||||
//uint32_t trig_count3_header; // 31
|
||||
//uint16_t trig_count3[NUM_TRIGGER_STAGES];
|
||||
uint32_t trig_logic0_header; // 32
|
||||
uint16_t trig_logic0[NUM_TRIGGER_STAGES];
|
||||
uint32_t trig_logic1_header; // 33
|
||||
uint16_t trig_logic1[NUM_TRIGGER_STAGES];
|
||||
//uint32_t trig_logic2_header; // 34
|
||||
//uint16_t trig_logic2[NUM_TRIGGER_STAGES];
|
||||
//uint32_t trig_logic3_header; // 35
|
||||
//uint16_t trig_logic3[NUM_TRIGGER_STAGES];
|
||||
uint32_t end_sync;
|
||||
};
|
||||
|
||||
#endif
|
||||
/*
|
||||
* This file is part of the libsigrok project.
|
||||
*
|
||||
* Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LIBDSLOGIC_HARDWARE_DSLOGIC_H
|
||||
#define LIBDSLOGIC_HARDWARE_DSLOGIC_H
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
/* Message logging helpers with subsystem-specific prefix string. */
|
||||
#define LOG_PREFIX "DSLogic Hardware: "
|
||||
#define ds_log(l, s, args...) ds_log(l, LOG_PREFIX s, ## args)
|
||||
#define ds_spew(s, args...) ds_spew(LOG_PREFIX s, ## args)
|
||||
#define ds_dbg(s, args...) ds_dbg(LOG_PREFIX s, ## args)
|
||||
#define ds_info(s, args...) ds_info(LOG_PREFIX s, ## args)
|
||||
#define ds_warn(s, args...) ds_warn(LOG_PREFIX s, ## args)
|
||||
#define ds_err(s, args...) ds_err(LOG_PREFIX s, ## args)
|
||||
|
||||
#define USB_INTERFACE 0
|
||||
#define USB_CONFIGURATION 1
|
||||
#define NUM_TRIGGER_STAGES 16
|
||||
#define TRIGGER_TYPE "01"
|
||||
|
||||
#define MAX_RENUM_DELAY_MS 3000
|
||||
#define NUM_SIMUL_TRANSFERS 64
|
||||
#define MAX_EMPTY_TRANSFERS (NUM_SIMUL_TRANSFERS * 2)
|
||||
|
||||
#define DSLOGIC_REQUIRED_VERSION_MAJOR 1
|
||||
|
||||
#define MAX_8BIT_SAMPLE_RATE DS_MHZ(24)
|
||||
#define MAX_16BIT_SAMPLE_RATE DS_MHZ(12)
|
||||
|
||||
/* 6 delay states of up to 256 clock ticks */
|
||||
#define MAX_SAMPLE_DELAY (6 * 256)
|
||||
|
||||
/* Software trigger implementation: positive values indicate trigger stage. */
|
||||
#define TRIGGER_FIRED -1
|
||||
|
||||
#define DEV_CAPS_16BIT_POS 0
|
||||
|
||||
#define DEV_CAPS_16BIT (1 << DEV_CAPS_16BIT_POS)
|
||||
|
||||
#define XC3S250E_BYTE_CNT 169216
|
||||
//#define XC6SLX9_BYTE_CNT 341160
|
||||
#define XC6SLX9_BYTE_CNT 340884
|
||||
//#define XC6SLX9_BYTE_CNT 340604
|
||||
|
||||
#define MAX_ANALOG_PROBES_NUM 9
|
||||
#define MAX_DSO_PROBES_NUM 2
|
||||
|
||||
struct DSLogic_profile {
|
||||
uint16_t vid;
|
||||
uint16_t pid;
|
||||
|
||||
const char *vendor;
|
||||
const char *model;
|
||||
const char *model_version;
|
||||
|
||||
const char *firmware;
|
||||
|
||||
const char *fpga_bit;
|
||||
|
||||
uint32_t dev_caps;
|
||||
};
|
||||
|
||||
static const struct DSLogic_profile supported_fx2[3] = {
|
||||
/*
|
||||
* DSLogic
|
||||
*/
|
||||
{0x2A0E, 0x0001, NULL, "DSLogic", NULL,
|
||||
"DSLogic.fw",
|
||||
"DSLogic.bin",
|
||||
DEV_CAPS_16BIT},
|
||||
|
||||
{ 0, 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
enum {
|
||||
DSLOGIC_ERROR = -1,
|
||||
DSLOGIC_INIT = 0,
|
||||
DSLOGIC_START = 1,
|
||||
DSLOGIC_TRIGGERED = 2,
|
||||
DSLOGIC_DATA = 3,
|
||||
DSLOGIC_STOP = 4,
|
||||
};
|
||||
|
||||
struct dev_context {
|
||||
const struct DSLogic_profile *profile;
|
||||
/*
|
||||
* Since we can't keep track of an DSLogic device after upgrading
|
||||
* the firmware (it renumerates into a different device address
|
||||
* after the upgrade) this is like a global lock. No device will open
|
||||
* until a proper delay after the last device was upgraded.
|
||||
*/
|
||||
int64_t fw_updated;
|
||||
|
||||
/* Device/capture settings */
|
||||
uint64_t cur_samplerate;
|
||||
uint64_t limit_samples;
|
||||
|
||||
/* Operational settings */
|
||||
gboolean sample_wide;
|
||||
gboolean clock_type;
|
||||
uint16_t op_mode;
|
||||
uint16_t trigger_mask[NUM_TRIGGER_STAGES];
|
||||
uint16_t trigger_value[NUM_TRIGGER_STAGES];
|
||||
int trigger_stage;
|
||||
uint16_t trigger_buffer[NUM_TRIGGER_STAGES];
|
||||
uint64_t vdiv0;
|
||||
uint64_t vdiv1;
|
||||
uint64_t timebase;
|
||||
gboolean coupling0;
|
||||
gboolean coupling1;
|
||||
gboolean en_ch0;
|
||||
gboolean en_ch1;
|
||||
uint8_t trigger_slope;
|
||||
uint8_t trigger_source;
|
||||
uint16_t trigger_vpos;
|
||||
uint32_t trigger_hpos;
|
||||
gboolean zero;
|
||||
|
||||
int num_samples;
|
||||
int submitted_transfers;
|
||||
int empty_transfer_count;
|
||||
|
||||
void *cb_data;
|
||||
unsigned int num_transfers;
|
||||
struct libusb_transfer **transfers;
|
||||
int *usbfd;
|
||||
|
||||
int pipe_fds[2];
|
||||
GIOChannel *channel;
|
||||
|
||||
int status;
|
||||
};
|
||||
|
||||
struct DSLogic_setting {
|
||||
uint32_t sync;
|
||||
uint16_t mode_header; // 0
|
||||
uint16_t mode;
|
||||
uint32_t divider_header; // 1-2
|
||||
uint32_t divider;
|
||||
uint32_t count_header; // 3-4
|
||||
uint32_t count;
|
||||
uint32_t trig_pos_header; // 5-6
|
||||
uint32_t trig_pos;
|
||||
uint16_t trig_glb_header; // 7
|
||||
uint16_t trig_glb;
|
||||
uint32_t trig_adp_header; // 10-11
|
||||
uint32_t trig_adp;
|
||||
uint32_t trig_sda_header; // 12-13
|
||||
uint32_t trig_sda;
|
||||
uint32_t trig_mask0_header; // 16
|
||||
uint16_t trig_mask0[NUM_TRIGGER_STAGES];
|
||||
uint32_t trig_mask1_header; // 17
|
||||
uint16_t trig_mask1[NUM_TRIGGER_STAGES];
|
||||
//uint32_t trig_mask2_header; // 18
|
||||
//uint16_t trig_mask2[NUM_TRIGGER_STAGES];
|
||||
//uint32_t trig_mask3_header; // 19
|
||||
//uint16_t trig_mask3[NUM_TRIGGER_STAGES];
|
||||
uint32_t trig_value0_header; // 20
|
||||
uint16_t trig_value0[NUM_TRIGGER_STAGES];
|
||||
uint32_t trig_value1_header; // 21
|
||||
uint16_t trig_value1[NUM_TRIGGER_STAGES];
|
||||
//uint32_t trig_value2_header; // 22
|
||||
//uint16_t trig_value2[NUM_TRIGGER_STAGES];
|
||||
//uint32_t trig_value3_header; // 23
|
||||
//uint16_t trig_value3[NUM_TRIGGER_STAGES];
|
||||
uint32_t trig_edge0_header; // 24
|
||||
uint16_t trig_edge0[NUM_TRIGGER_STAGES];
|
||||
uint32_t trig_edge1_header; // 25
|
||||
uint16_t trig_edge1[NUM_TRIGGER_STAGES];
|
||||
//uint32_t trig_edge2_header; // 26
|
||||
//uint16_t trig_edge2[NUM_TRIGGER_STAGES];
|
||||
//uint32_t trig_edge3_header; // 27
|
||||
//uint16_t trig_edge3[NUM_TRIGGER_STAGES];
|
||||
uint32_t trig_count0_header; // 28
|
||||
uint16_t trig_count0[NUM_TRIGGER_STAGES];
|
||||
uint32_t trig_count1_header; // 29
|
||||
uint16_t trig_count1[NUM_TRIGGER_STAGES];
|
||||
//uint32_t trig_count2_header; // 30
|
||||
//uint16_t trig_count2[NUM_TRIGGER_STAGES];
|
||||
//uint32_t trig_count3_header; // 31
|
||||
//uint16_t trig_count3[NUM_TRIGGER_STAGES];
|
||||
uint32_t trig_logic0_header; // 32
|
||||
uint16_t trig_logic0[NUM_TRIGGER_STAGES];
|
||||
uint32_t trig_logic1_header; // 33
|
||||
uint16_t trig_logic1[NUM_TRIGGER_STAGES];
|
||||
//uint32_t trig_logic2_header; // 34
|
||||
//uint16_t trig_logic2[NUM_TRIGGER_STAGES];
|
||||
//uint32_t trig_logic3_header; // 35
|
||||
//uint16_t trig_logic3[NUM_TRIGGER_STAGES];
|
||||
uint32_t end_sync;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,143 +1,143 @@
|
||||
/*
|
||||
* This file is part of the libsigrok project.
|
||||
*
|
||||
* Copyright (C) 2013 Bert Vermeulen <bert@biot.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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Helper functions for the Cypress EZ-USB / FX2 series chips.
|
||||
*/
|
||||
|
||||
#include <libusb.h>
|
||||
#include <glib.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include "libsigrok.h"
|
||||
#include "libsigrok-internal.h"
|
||||
|
||||
/* Message logging helpers with subsystem-specific prefix string. */
|
||||
#define LOG_PREFIX "ezusb: "
|
||||
#define sr_log(l, s, args...) sr_log(l, LOG_PREFIX s, ## args)
|
||||
#define sr_spew(s, args...) sr_spew(LOG_PREFIX s, ## args)
|
||||
#define sr_dbg(s, args...) sr_dbg(LOG_PREFIX s, ## args)
|
||||
#define sr_info(s, args...) sr_info(LOG_PREFIX s, ## args)
|
||||
#define sr_warn(s, args...) sr_warn(LOG_PREFIX s, ## args)
|
||||
#define sr_err(s, args...) sr_err(LOG_PREFIX s, ## args)
|
||||
|
||||
SR_PRIV int ezusb_reset(struct libusb_device_handle *hdl, int set_clear)
|
||||
{
|
||||
int ret;
|
||||
unsigned char buf[1];
|
||||
|
||||
sr_info("setting CPU reset mode %s...",
|
||||
set_clear ? "on" : "off");
|
||||
buf[0] = set_clear ? 1 : 0;
|
||||
ret = libusb_control_transfer(hdl, LIBUSB_REQUEST_TYPE_VENDOR, 0xa0,
|
||||
0xe600, 0x0000, buf, 1, 100);
|
||||
if (ret < 0)
|
||||
sr_err("Unable to send control request: %s.",
|
||||
libusb_error_name(ret));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
SR_PRIV int ezusb_install_firmware(libusb_device_handle *hdl,
|
||||
const char *filename)
|
||||
{
|
||||
FILE *fw;
|
||||
int offset, chunksize, ret, result;
|
||||
unsigned char buf[4096];
|
||||
|
||||
sr_info("Uploading firmware at %s", filename);
|
||||
if ((fw = g_fopen(filename, "rb")) == NULL) {
|
||||
sr_err("Unable to open firmware file %s for reading: %s",
|
||||
filename, strerror(errno));
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
result = SR_OK;
|
||||
offset = 0;
|
||||
while (1) {
|
||||
chunksize = fread(buf, 1, 4096, fw);
|
||||
if (chunksize == 0)
|
||||
break;
|
||||
ret = libusb_control_transfer(hdl, LIBUSB_REQUEST_TYPE_VENDOR |
|
||||
LIBUSB_ENDPOINT_OUT, 0xa0, offset,
|
||||
0x0000, buf, chunksize, 100);
|
||||
if (ret < 0) {
|
||||
sr_err("Unable to send firmware to device: %s.",
|
||||
libusb_error_name(ret));
|
||||
result = SR_ERR;
|
||||
break;
|
||||
}
|
||||
sr_info("Uploaded %d bytes", chunksize);
|
||||
offset += chunksize;
|
||||
}
|
||||
fclose(fw);
|
||||
sr_info("Firmware upload done");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SR_PRIV int ezusb_upload_firmware(libusb_device *dev, int configuration,
|
||||
const char *filename)
|
||||
{
|
||||
struct libusb_device_handle *hdl;
|
||||
int ret;
|
||||
|
||||
sr_info("uploading firmware to device on %d.%d",
|
||||
libusb_get_bus_number(dev), libusb_get_device_address(dev));
|
||||
|
||||
if ((ret = libusb_open(dev, &hdl)) < 0) {
|
||||
sr_err("failed to open device: %s.", libusb_error_name(ret));
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
/*
|
||||
* The libusbx darwin backend is broken: it can report a kernel driver being
|
||||
* active, but detaching it always returns an error.
|
||||
*/
|
||||
#if !defined(__APPLE__)
|
||||
if (libusb_kernel_driver_active(hdl, 0) == 1) {
|
||||
if ((ret = libusb_detach_kernel_driver(hdl, 0)) < 0) {
|
||||
sr_err("failed to detach kernel driver: %s",
|
||||
libusb_error_name(ret));
|
||||
return SR_ERR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((ret = libusb_set_configuration(hdl, configuration)) < 0) {
|
||||
sr_err("Unable to set configuration: %s",
|
||||
libusb_error_name(ret));
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
if ((ezusb_reset(hdl, 1)) < 0)
|
||||
return SR_ERR;
|
||||
|
||||
if (ezusb_install_firmware(hdl, filename) < 0)
|
||||
return SR_ERR;
|
||||
|
||||
if ((ezusb_reset(hdl, 0)) < 0)
|
||||
return SR_ERR;
|
||||
|
||||
libusb_close(hdl);
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
/*
|
||||
* This file is part of the libsigrok project.
|
||||
*
|
||||
* Copyright (C) 2013 Bert Vermeulen <bert@biot.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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Helper functions for the Cypress EZ-USB / FX2 series chips.
|
||||
*/
|
||||
|
||||
#include <libusb.h>
|
||||
#include <glib.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include "libsigrok.h"
|
||||
#include "libsigrok-internal.h"
|
||||
|
||||
/* Message logging helpers with subsystem-specific prefix string. */
|
||||
#define LOG_PREFIX "ezusb: "
|
||||
#define sr_log(l, s, args...) sr_log(l, LOG_PREFIX s, ## args)
|
||||
#define sr_spew(s, args...) sr_spew(LOG_PREFIX s, ## args)
|
||||
#define sr_dbg(s, args...) sr_dbg(LOG_PREFIX s, ## args)
|
||||
#define sr_info(s, args...) sr_info(LOG_PREFIX s, ## args)
|
||||
#define sr_warn(s, args...) sr_warn(LOG_PREFIX s, ## args)
|
||||
#define sr_err(s, args...) sr_err(LOG_PREFIX s, ## args)
|
||||
|
||||
SR_PRIV int ezusb_reset(struct libusb_device_handle *hdl, int set_clear)
|
||||
{
|
||||
int ret;
|
||||
unsigned char buf[1];
|
||||
|
||||
sr_info("setting CPU reset mode %s...",
|
||||
set_clear ? "on" : "off");
|
||||
buf[0] = set_clear ? 1 : 0;
|
||||
ret = libusb_control_transfer(hdl, LIBUSB_REQUEST_TYPE_VENDOR, 0xa0,
|
||||
0xe600, 0x0000, buf, 1, 100);
|
||||
if (ret < 0)
|
||||
sr_err("Unable to send control request: %s.",
|
||||
libusb_error_name(ret));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
SR_PRIV int ezusb_install_firmware(libusb_device_handle *hdl,
|
||||
const char *filename)
|
||||
{
|
||||
FILE *fw;
|
||||
int offset, chunksize, ret, result;
|
||||
unsigned char buf[4096];
|
||||
|
||||
sr_info("Uploading firmware at %s", filename);
|
||||
if ((fw = g_fopen(filename, "rb")) == NULL) {
|
||||
sr_err("Unable to open firmware file %s for reading: %s",
|
||||
filename, strerror(errno));
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
result = SR_OK;
|
||||
offset = 0;
|
||||
while (1) {
|
||||
chunksize = fread(buf, 1, 4096, fw);
|
||||
if (chunksize == 0)
|
||||
break;
|
||||
ret = libusb_control_transfer(hdl, LIBUSB_REQUEST_TYPE_VENDOR |
|
||||
LIBUSB_ENDPOINT_OUT, 0xa0, offset,
|
||||
0x0000, buf, chunksize, 100);
|
||||
if (ret < 0) {
|
||||
sr_err("Unable to send firmware to device: %s.",
|
||||
libusb_error_name(ret));
|
||||
result = SR_ERR;
|
||||
break;
|
||||
}
|
||||
sr_info("Uploaded %d bytes", chunksize);
|
||||
offset += chunksize;
|
||||
}
|
||||
fclose(fw);
|
||||
sr_info("Firmware upload done");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SR_PRIV int ezusb_upload_firmware(libusb_device *dev, int configuration,
|
||||
const char *filename)
|
||||
{
|
||||
struct libusb_device_handle *hdl;
|
||||
int ret;
|
||||
|
||||
sr_info("uploading firmware to device on %d.%d",
|
||||
libusb_get_bus_number(dev), libusb_get_device_address(dev));
|
||||
|
||||
if ((ret = libusb_open(dev, &hdl)) < 0) {
|
||||
sr_err("failed to open device: %s.", libusb_error_name(ret));
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
/*
|
||||
* The libusbx darwin backend is broken: it can report a kernel driver being
|
||||
* active, but detaching it always returns an error.
|
||||
*/
|
||||
#if !defined(__APPLE__)
|
||||
if (libusb_kernel_driver_active(hdl, 0) == 1) {
|
||||
if ((ret = libusb_detach_kernel_driver(hdl, 0)) < 0) {
|
||||
sr_err("failed to detach kernel driver: %s",
|
||||
libusb_error_name(ret));
|
||||
return SR_ERR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((ret = libusb_set_configuration(hdl, configuration)) < 0) {
|
||||
sr_err("Unable to set configuration: %s",
|
||||
libusb_error_name(ret));
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
if ((ezusb_reset(hdl, 1)) < 0)
|
||||
return SR_ERR;
|
||||
|
||||
if (ezusb_install_firmware(hdl, filename) < 0)
|
||||
return SR_ERR;
|
||||
|
||||
if ((ezusb_reset(hdl, 0)) < 0)
|
||||
return SR_ERR;
|
||||
|
||||
libusb_close(hdl);
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
@ -1,245 +1,245 @@
|
||||
/*
|
||||
* This file is part of the libsigrok project.
|
||||
*
|
||||
* Copyright (C) 2013 Bert Vermeulen <bert@biot.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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <glib.h>
|
||||
#include <libusb.h>
|
||||
#include "libsigrok.h"
|
||||
#include "libsigrok-internal.h"
|
||||
|
||||
/* SR_CONF_CONN takes one of these: */
|
||||
#define CONN_USB_VIDPID "^([0-9a-z]{4})\\.([0-9a-z]{4})$"
|
||||
#define CONN_USB_BUSADDR "^(\\d+)\\.(\\d+)$"
|
||||
|
||||
/* Some USBTMC-specific enums, as defined in the USBTMC standard. */
|
||||
#define SUBCLASS_USBTMC 0x03
|
||||
#define USBTMC_USB488 0x01
|
||||
|
||||
/* Message logging helpers with subsystem-specific prefix string. */
|
||||
#define LOG_PREFIX "usb: "
|
||||
#define sr_log(l, s, args...) sr_log(l, LOG_PREFIX s, ## args)
|
||||
#define sr_spew(s, args...) sr_spew(LOG_PREFIX s, ## args)
|
||||
#define sr_dbg(s, args...) sr_dbg(LOG_PREFIX s, ## args)
|
||||
#define sr_info(s, args...) sr_info(LOG_PREFIX s, ## args)
|
||||
#define sr_warn(s, args...) sr_warn(LOG_PREFIX s, ## args)
|
||||
#define sr_err(s, args...) sr_err(LOG_PREFIX s, ## args)
|
||||
|
||||
/**
|
||||
* Find USB devices according to a connection string.
|
||||
*
|
||||
* @param usb_ctx libusb context to use while scanning.
|
||||
* @param conn Connection string specifying the device(s) to match. This
|
||||
* can be of the form "<bus>.<address>", or "<vendorid>.<productid>".
|
||||
*
|
||||
* @return A GSList of struct sr_usb_dev_inst, with bus and address fields
|
||||
* matching the device that matched the connection string. The GSList and
|
||||
* its contents must be freed by the caller.
|
||||
*/
|
||||
SR_PRIV GSList *sr_usb_find(libusb_context *usb_ctx, const char *conn)
|
||||
{
|
||||
struct sr_usb_dev_inst *usb;
|
||||
struct libusb_device **devlist;
|
||||
struct libusb_device_descriptor des;
|
||||
GSList *devices;
|
||||
GRegex *reg;
|
||||
GMatchInfo *match;
|
||||
int vid, pid, bus, addr, b, a, ret, i;
|
||||
char *mstr;
|
||||
|
||||
vid = pid = bus = addr = 0;
|
||||
reg = g_regex_new(CONN_USB_VIDPID, 0, 0, NULL);
|
||||
if (g_regex_match(reg, conn, 0, &match)) {
|
||||
if ((mstr = g_match_info_fetch(match, 1)))
|
||||
vid = strtoul(mstr, NULL, 16);
|
||||
g_free(mstr);
|
||||
|
||||
if ((mstr = g_match_info_fetch(match, 2)))
|
||||
pid = strtoul(mstr, NULL, 16);
|
||||
g_free(mstr);
|
||||
sr_dbg("Trying to find USB device with VID:PID = %04x:%04x.",
|
||||
vid, pid);
|
||||
} else {
|
||||
//g_match_info_unref(match);
|
||||
g_match_info_free(match);
|
||||
g_regex_unref(reg);
|
||||
reg = g_regex_new(CONN_USB_BUSADDR, 0, 0, NULL);
|
||||
if (g_regex_match(reg, conn, 0, &match)) {
|
||||
if ((mstr = g_match_info_fetch(match, 1)))
|
||||
bus = strtoul(mstr, NULL, 10);
|
||||
g_free(mstr);
|
||||
|
||||
if ((mstr = g_match_info_fetch(match, 2)))
|
||||
addr = strtoul(mstr, NULL, 10);
|
||||
g_free(mstr);
|
||||
sr_dbg("Trying to find USB device with bus.address = "
|
||||
"%d.%d.", bus, addr);
|
||||
}
|
||||
}
|
||||
//g_match_info_unref(match);
|
||||
g_match_info_free(match);
|
||||
g_regex_unref(reg);
|
||||
|
||||
if (vid + pid + bus + addr == 0) {
|
||||
sr_err("Neither VID:PID nor bus.address was specified.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (bus > 64) {
|
||||
sr_err("Invalid bus specified: %d.", bus);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (addr > 127) {
|
||||
sr_err("Invalid address specified: %d.", addr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Looks like a valid USB device specification, but is it connected? */
|
||||
devices = NULL;
|
||||
libusb_get_device_list(usb_ctx, &devlist);
|
||||
for (i = 0; devlist[i]; i++) {
|
||||
if ((ret = libusb_get_device_descriptor(devlist[i], &des))) {
|
||||
sr_err("Failed to get device descriptor: %s.",
|
||||
libusb_error_name(ret));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vid + pid && (des.idVendor != vid || des.idProduct != pid))
|
||||
continue;
|
||||
|
||||
b = libusb_get_bus_number(devlist[i]);
|
||||
a = libusb_get_device_address(devlist[i]);
|
||||
if (bus + addr && (b != bus || a != addr))
|
||||
continue;
|
||||
|
||||
sr_dbg("Found USB device (VID:PID = %04x:%04x, bus.address = "
|
||||
"%d.%d).", des.idVendor, des.idProduct, b, a);
|
||||
|
||||
usb = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]),
|
||||
libusb_get_device_address(devlist[i]), NULL);
|
||||
devices = g_slist_append(devices, usb);
|
||||
}
|
||||
libusb_free_device_list(devlist, 1);
|
||||
|
||||
sr_dbg("Found %d device(s).", g_slist_length(devices));
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find USB devices supporting the USBTMC class
|
||||
*
|
||||
* @param usb_ctx libusb context to use while scanning.
|
||||
*
|
||||
* @return A GSList of struct sr_usb_dev_inst, with bus and address fields
|
||||
* indicating devices with USBTMC support.
|
||||
*/
|
||||
SR_PRIV GSList *sr_usb_find_usbtmc(libusb_context *usb_ctx)
|
||||
{
|
||||
struct sr_usb_dev_inst *usb;
|
||||
struct libusb_device **devlist;
|
||||
struct libusb_device_descriptor des;
|
||||
struct libusb_config_descriptor *confdes;
|
||||
const struct libusb_interface_descriptor *intfdes;
|
||||
GSList *devices;
|
||||
int confidx, intfidx, ret, i;
|
||||
|
||||
devices = NULL;
|
||||
libusb_get_device_list(usb_ctx, &devlist);
|
||||
for (i = 0; devlist[i]; i++) {
|
||||
if ((ret = libusb_get_device_descriptor(devlist[i], &des))) {
|
||||
sr_err("Failed to get device descriptor: %s.",
|
||||
libusb_error_name(ret));
|
||||
continue;
|
||||
}
|
||||
|
||||
for (confidx = 0; confidx < des.bNumConfigurations; confidx++) {
|
||||
if (libusb_get_config_descriptor(devlist[i], confidx, &confdes) != 0) {
|
||||
sr_err("Failed to get configuration descriptor.");
|
||||
break;
|
||||
}
|
||||
for (intfidx = 0; intfidx < confdes->bNumInterfaces; intfidx++) {
|
||||
intfdes = confdes->interface[intfidx].altsetting;
|
||||
if (intfdes->bInterfaceClass != LIBUSB_CLASS_APPLICATION
|
||||
|| intfdes->bInterfaceSubClass != SUBCLASS_USBTMC
|
||||
|| intfdes->bInterfaceProtocol != USBTMC_USB488)
|
||||
continue;
|
||||
sr_dbg("Found USBTMC device (VID:PID = %04x:%04x, bus.address = "
|
||||
"%d.%d).", des.idVendor, des.idProduct,
|
||||
libusb_get_bus_number(devlist[i]),
|
||||
libusb_get_device_address(devlist[i]));
|
||||
|
||||
usb = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]),
|
||||
libusb_get_device_address(devlist[i]), NULL);
|
||||
devices = g_slist_append(devices, usb);
|
||||
}
|
||||
libusb_free_config_descriptor(confdes);
|
||||
}
|
||||
}
|
||||
libusb_free_device_list(devlist, 1);
|
||||
|
||||
sr_dbg("Found %d device(s).", g_slist_length(devices));
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
SR_PRIV int sr_usb_open(libusb_context *usb_ctx, struct sr_usb_dev_inst *usb)
|
||||
{
|
||||
struct libusb_device **devlist;
|
||||
struct libusb_device_descriptor des;
|
||||
int ret, r, cnt, i, a, b;
|
||||
|
||||
sr_dbg("Trying to open USB device %d.%d.", usb->bus, usb->address);
|
||||
|
||||
if ((cnt = libusb_get_device_list(usb_ctx, &devlist)) < 0) {
|
||||
sr_err("Failed to retrieve device list: %s.",
|
||||
libusb_error_name(cnt));
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
ret = SR_ERR;
|
||||
for (i = 0; i < cnt; i++) {
|
||||
if ((r = libusb_get_device_descriptor(devlist[i], &des)) < 0) {
|
||||
sr_err("Failed to get device descriptor: %s.",
|
||||
libusb_error_name(r));
|
||||
continue;
|
||||
}
|
||||
|
||||
b = libusb_get_bus_number(devlist[i]);
|
||||
a = libusb_get_device_address(devlist[i]);
|
||||
if (b != usb->bus || a != usb->address)
|
||||
continue;
|
||||
|
||||
if ((r = libusb_open(devlist[i], &usb->devhdl)) < 0) {
|
||||
sr_err("Failed to open device: %s.",
|
||||
libusb_error_name(r));
|
||||
break;
|
||||
}
|
||||
|
||||
sr_dbg("Opened USB device (VID:PID = %04x:%04x, bus.address = "
|
||||
"%d.%d).", des.idVendor, des.idProduct, b, a);
|
||||
|
||||
ret = SR_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
libusb_free_device_list(devlist, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
* This file is part of the libsigrok project.
|
||||
*
|
||||
* Copyright (C) 2013 Bert Vermeulen <bert@biot.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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <glib.h>
|
||||
#include <libusb.h>
|
||||
#include "libsigrok.h"
|
||||
#include "libsigrok-internal.h"
|
||||
|
||||
/* SR_CONF_CONN takes one of these: */
|
||||
#define CONN_USB_VIDPID "^([0-9a-z]{4})\\.([0-9a-z]{4})$"
|
||||
#define CONN_USB_BUSADDR "^(\\d+)\\.(\\d+)$"
|
||||
|
||||
/* Some USBTMC-specific enums, as defined in the USBTMC standard. */
|
||||
#define SUBCLASS_USBTMC 0x03
|
||||
#define USBTMC_USB488 0x01
|
||||
|
||||
/* Message logging helpers with subsystem-specific prefix string. */
|
||||
#define LOG_PREFIX "usb: "
|
||||
#define sr_log(l, s, args...) sr_log(l, LOG_PREFIX s, ## args)
|
||||
#define sr_spew(s, args...) sr_spew(LOG_PREFIX s, ## args)
|
||||
#define sr_dbg(s, args...) sr_dbg(LOG_PREFIX s, ## args)
|
||||
#define sr_info(s, args...) sr_info(LOG_PREFIX s, ## args)
|
||||
#define sr_warn(s, args...) sr_warn(LOG_PREFIX s, ## args)
|
||||
#define sr_err(s, args...) sr_err(LOG_PREFIX s, ## args)
|
||||
|
||||
/**
|
||||
* Find USB devices according to a connection string.
|
||||
*
|
||||
* @param usb_ctx libusb context to use while scanning.
|
||||
* @param conn Connection string specifying the device(s) to match. This
|
||||
* can be of the form "<bus>.<address>", or "<vendorid>.<productid>".
|
||||
*
|
||||
* @return A GSList of struct sr_usb_dev_inst, with bus and address fields
|
||||
* matching the device that matched the connection string. The GSList and
|
||||
* its contents must be freed by the caller.
|
||||
*/
|
||||
SR_PRIV GSList *sr_usb_find(libusb_context *usb_ctx, const char *conn)
|
||||
{
|
||||
struct sr_usb_dev_inst *usb;
|
||||
struct libusb_device **devlist;
|
||||
struct libusb_device_descriptor des;
|
||||
GSList *devices;
|
||||
GRegex *reg;
|
||||
GMatchInfo *match;
|
||||
int vid, pid, bus, addr, b, a, ret, i;
|
||||
char *mstr;
|
||||
|
||||
vid = pid = bus = addr = 0;
|
||||
reg = g_regex_new(CONN_USB_VIDPID, 0, 0, NULL);
|
||||
if (g_regex_match(reg, conn, 0, &match)) {
|
||||
if ((mstr = g_match_info_fetch(match, 1)))
|
||||
vid = strtoul(mstr, NULL, 16);
|
||||
g_free(mstr);
|
||||
|
||||
if ((mstr = g_match_info_fetch(match, 2)))
|
||||
pid = strtoul(mstr, NULL, 16);
|
||||
g_free(mstr);
|
||||
sr_dbg("Trying to find USB device with VID:PID = %04x:%04x.",
|
||||
vid, pid);
|
||||
} else {
|
||||
//g_match_info_unref(match);
|
||||
g_match_info_free(match);
|
||||
g_regex_unref(reg);
|
||||
reg = g_regex_new(CONN_USB_BUSADDR, 0, 0, NULL);
|
||||
if (g_regex_match(reg, conn, 0, &match)) {
|
||||
if ((mstr = g_match_info_fetch(match, 1)))
|
||||
bus = strtoul(mstr, NULL, 10);
|
||||
g_free(mstr);
|
||||
|
||||
if ((mstr = g_match_info_fetch(match, 2)))
|
||||
addr = strtoul(mstr, NULL, 10);
|
||||
g_free(mstr);
|
||||
sr_dbg("Trying to find USB device with bus.address = "
|
||||
"%d.%d.", bus, addr);
|
||||
}
|
||||
}
|
||||
//g_match_info_unref(match);
|
||||
g_match_info_free(match);
|
||||
g_regex_unref(reg);
|
||||
|
||||
if (vid + pid + bus + addr == 0) {
|
||||
sr_err("Neither VID:PID nor bus.address was specified.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (bus > 64) {
|
||||
sr_err("Invalid bus specified: %d.", bus);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (addr > 127) {
|
||||
sr_err("Invalid address specified: %d.", addr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Looks like a valid USB device specification, but is it connected? */
|
||||
devices = NULL;
|
||||
libusb_get_device_list(usb_ctx, &devlist);
|
||||
for (i = 0; devlist[i]; i++) {
|
||||
if ((ret = libusb_get_device_descriptor(devlist[i], &des))) {
|
||||
sr_err("Failed to get device descriptor: %s.",
|
||||
libusb_error_name(ret));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vid + pid && (des.idVendor != vid || des.idProduct != pid))
|
||||
continue;
|
||||
|
||||
b = libusb_get_bus_number(devlist[i]);
|
||||
a = libusb_get_device_address(devlist[i]);
|
||||
if (bus + addr && (b != bus || a != addr))
|
||||
continue;
|
||||
|
||||
sr_dbg("Found USB device (VID:PID = %04x:%04x, bus.address = "
|
||||
"%d.%d).", des.idVendor, des.idProduct, b, a);
|
||||
|
||||
usb = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]),
|
||||
libusb_get_device_address(devlist[i]), NULL);
|
||||
devices = g_slist_append(devices, usb);
|
||||
}
|
||||
libusb_free_device_list(devlist, 1);
|
||||
|
||||
sr_dbg("Found %d device(s).", g_slist_length(devices));
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find USB devices supporting the USBTMC class
|
||||
*
|
||||
* @param usb_ctx libusb context to use while scanning.
|
||||
*
|
||||
* @return A GSList of struct sr_usb_dev_inst, with bus and address fields
|
||||
* indicating devices with USBTMC support.
|
||||
*/
|
||||
SR_PRIV GSList *sr_usb_find_usbtmc(libusb_context *usb_ctx)
|
||||
{
|
||||
struct sr_usb_dev_inst *usb;
|
||||
struct libusb_device **devlist;
|
||||
struct libusb_device_descriptor des;
|
||||
struct libusb_config_descriptor *confdes;
|
||||
const struct libusb_interface_descriptor *intfdes;
|
||||
GSList *devices;
|
||||
int confidx, intfidx, ret, i;
|
||||
|
||||
devices = NULL;
|
||||
libusb_get_device_list(usb_ctx, &devlist);
|
||||
for (i = 0; devlist[i]; i++) {
|
||||
if ((ret = libusb_get_device_descriptor(devlist[i], &des))) {
|
||||
sr_err("Failed to get device descriptor: %s.",
|
||||
libusb_error_name(ret));
|
||||
continue;
|
||||
}
|
||||
|
||||
for (confidx = 0; confidx < des.bNumConfigurations; confidx++) {
|
||||
if (libusb_get_config_descriptor(devlist[i], confidx, &confdes) != 0) {
|
||||
sr_err("Failed to get configuration descriptor.");
|
||||
break;
|
||||
}
|
||||
for (intfidx = 0; intfidx < confdes->bNumInterfaces; intfidx++) {
|
||||
intfdes = confdes->interface[intfidx].altsetting;
|
||||
if (intfdes->bInterfaceClass != LIBUSB_CLASS_APPLICATION
|
||||
|| intfdes->bInterfaceSubClass != SUBCLASS_USBTMC
|
||||
|| intfdes->bInterfaceProtocol != USBTMC_USB488)
|
||||
continue;
|
||||
sr_dbg("Found USBTMC device (VID:PID = %04x:%04x, bus.address = "
|
||||
"%d.%d).", des.idVendor, des.idProduct,
|
||||
libusb_get_bus_number(devlist[i]),
|
||||
libusb_get_device_address(devlist[i]));
|
||||
|
||||
usb = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]),
|
||||
libusb_get_device_address(devlist[i]), NULL);
|
||||
devices = g_slist_append(devices, usb);
|
||||
}
|
||||
libusb_free_config_descriptor(confdes);
|
||||
}
|
||||
}
|
||||
libusb_free_device_list(devlist, 1);
|
||||
|
||||
sr_dbg("Found %d device(s).", g_slist_length(devices));
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
SR_PRIV int sr_usb_open(libusb_context *usb_ctx, struct sr_usb_dev_inst *usb)
|
||||
{
|
||||
struct libusb_device **devlist;
|
||||
struct libusb_device_descriptor des;
|
||||
int ret, r, cnt, i, a, b;
|
||||
|
||||
sr_dbg("Trying to open USB device %d.%d.", usb->bus, usb->address);
|
||||
|
||||
if ((cnt = libusb_get_device_list(usb_ctx, &devlist)) < 0) {
|
||||
sr_err("Failed to retrieve device list: %s.",
|
||||
libusb_error_name(cnt));
|
||||
return SR_ERR;
|
||||
}
|
||||
|
||||
ret = SR_ERR;
|
||||
for (i = 0; i < cnt; i++) {
|
||||
if ((r = libusb_get_device_descriptor(devlist[i], &des)) < 0) {
|
||||
sr_err("Failed to get device descriptor: %s.",
|
||||
libusb_error_name(r));
|
||||
continue;
|
||||
}
|
||||
|
||||
b = libusb_get_bus_number(devlist[i]);
|
||||
a = libusb_get_device_address(devlist[i]);
|
||||
if (b != usb->bus || a != usb->address)
|
||||
continue;
|
||||
|
||||
if ((r = libusb_open(devlist[i], &usb->devhdl)) < 0) {
|
||||
sr_err("Failed to open device: %s.",
|
||||
libusb_error_name(r));
|
||||
break;
|
||||
}
|
||||
|
||||
sr_dbg("Opened USB device (VID:PID = %04x:%04x, bus.address = "
|
||||
"%d.%d).", des.idVendor, des.idProduct, b, a);
|
||||
|
||||
ret = SR_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
libusb_free_device_list(devlist, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -85,6 +85,13 @@ struct dev_context {
|
||||
void *cb_data;
|
||||
int64_t starttime;
|
||||
int stop;
|
||||
gboolean en_ch0;
|
||||
gboolean en_ch1;
|
||||
uint64_t vdiv0;
|
||||
uint64_t vdiv1;
|
||||
uint64_t timebase;
|
||||
gboolean coupling0;
|
||||
gboolean coupling1;
|
||||
|
||||
int trigger_stage;
|
||||
uint16_t trigger_mask;
|
||||
@ -192,6 +199,11 @@ static GSList *hw_scan(GSList *options)
|
||||
devc->limit_samples = 0;
|
||||
devc->limit_msec = 0;
|
||||
devc->sample_generator = PATTERN_SINE;
|
||||
devc->vdiv0 = 1000;
|
||||
devc->vdiv1 = 1000;
|
||||
devc->timebase = 100;
|
||||
devc->coupling0 = FALSE;
|
||||
devc->coupling1 = FALSE;
|
||||
|
||||
sdi->priv = devc;
|
||||
|
||||
@ -290,6 +302,27 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi)
|
||||
case SR_CONF_PATTERN_MODE:
|
||||
*data = g_variant_new_string(pattern_strings[devc->sample_generator]);
|
||||
break;
|
||||
case SR_CONF_VDIV0:
|
||||
*data = g_variant_new_uint64(devc->vdiv0);
|
||||
break;
|
||||
case SR_CONF_VDIV1:
|
||||
*data = g_variant_new_uint64(devc->vdiv1);
|
||||
break;
|
||||
case SR_CONF_TIMEBASE:
|
||||
*data = g_variant_new_uint64(devc->timebase);
|
||||
break;
|
||||
case SR_CONF_COUPLING0:
|
||||
*data = g_variant_new_uint64(devc->coupling0);
|
||||
break;
|
||||
case SR_CONF_COUPLING1:
|
||||
*data = g_variant_new_uint64(devc->coupling1);
|
||||
break;
|
||||
case SR_CONF_EN_CH0:
|
||||
*data = g_variant_new_uint64(devc->en_ch0);
|
||||
break;
|
||||
case SR_CONF_EN_CH1:
|
||||
*data = g_variant_new_uint64(devc->en_ch1);
|
||||
break;
|
||||
default:
|
||||
return SR_ERR_NA;
|
||||
}
|
||||
@ -380,7 +413,42 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi)
|
||||
}
|
||||
sr_dbg("%s: setting pattern to %d",
|
||||
__func__, devc->sample_generator);
|
||||
} else {
|
||||
} else if (id == SR_CONF_EN_CH0) {
|
||||
devc->en_ch0 = g_variant_get_boolean(data);
|
||||
sr_dbg("%s: setting ENABLE of channel 0 to %d", __func__,
|
||||
devc->en_ch0);
|
||||
ret = SR_OK;
|
||||
} else if (id == SR_CONF_EN_CH1) {
|
||||
devc->en_ch1 = g_variant_get_boolean(data);
|
||||
sr_dbg("%s: setting ENABLE of channel 1 to %d", __func__,
|
||||
devc->en_ch1);
|
||||
ret = SR_OK;
|
||||
} else if (id == SR_CONF_VDIV0) {
|
||||
devc->vdiv0 = g_variant_get_uint64(data);
|
||||
sr_dbg("%s: setting VDIV of channel 0 to %" PRIu64, __func__,
|
||||
devc->vdiv0);
|
||||
ret = SR_OK;
|
||||
} else if (id == SR_CONF_VDIV1) {
|
||||
devc->vdiv1 = g_variant_get_uint64(data);
|
||||
sr_dbg("%s: setting VDIV of channel 1 to %" PRIu64, __func__,
|
||||
devc->vdiv1);
|
||||
ret = SR_OK;
|
||||
} else if (id == SR_CONF_TIMEBASE) {
|
||||
devc->timebase = g_variant_get_uint64(data);
|
||||
sr_dbg("%s: setting TIMEBASE to %" PRIu64, __func__,
|
||||
devc->timebase);
|
||||
ret = SR_OK;
|
||||
} else if (id == SR_CONF_COUPLING0) {
|
||||
devc->coupling0 = g_variant_get_boolean(data);
|
||||
sr_dbg("%s: setting AC COUPLING of channel 0 to %d", __func__,
|
||||
devc->coupling0);
|
||||
ret = SR_OK;
|
||||
} else if (id == SR_CONF_COUPLING1) {
|
||||
devc->coupling1 = g_variant_get_boolean(data);
|
||||
sr_dbg("%s: setting AC COUPLING of channel 1 to %d", __func__,
|
||||
devc->coupling1);
|
||||
ret = SR_OK;
|
||||
} else {
|
||||
ret = SR_ERR_NA;
|
||||
}
|
||||
|
||||
|
@ -81,10 +81,14 @@ static struct sr_config_info sr_config_info_data[] = {
|
||||
"Time base", NULL},
|
||||
{SR_CONF_FILTER, SR_T_CHAR, "filter",
|
||||
"Filter targets", NULL},
|
||||
{SR_CONF_VDIV, SR_T_RATIONAL_VOLT, "vdiv",
|
||||
{SR_CONF_VDIV0, SR_T_RATIONAL_VOLT, "vdiv",
|
||||
"Volts/div", NULL},
|
||||
{SR_CONF_COUPLING, SR_T_CHAR, "coupling",
|
||||
{SR_CONF_VDIV1, SR_T_RATIONAL_VOLT, "vdiv",
|
||||
"Volts/div", NULL},
|
||||
{SR_CONF_COUPLING0, SR_T_CHAR, "coupling",
|
||||
"Coupling", NULL},
|
||||
{SR_CONF_COUPLING1, SR_T_CHAR, "coupling",
|
||||
"Coupling", NULL},
|
||||
{SR_CONF_DATALOG, SR_T_BOOL, "datalog",
|
||||
"Datalog", NULL},
|
||||
{SR_CONF_OPERATION_MODE, SR_T_CHAR, "operation",
|
||||
|
@ -689,6 +689,9 @@ enum {
|
||||
/** Trigger source. */
|
||||
SR_CONF_TRIGGER_SOURCE,
|
||||
|
||||
/** Trigger Value. */
|
||||
SR_CONF_TRIGGER_VALUE,
|
||||
|
||||
/** Horizontal trigger position. */
|
||||
SR_CONF_HORIZ_TRIGGERPOS,
|
||||
|
||||
@ -701,11 +704,23 @@ enum {
|
||||
/** Filter. */
|
||||
SR_CONF_FILTER,
|
||||
|
||||
/** DSO configure sync */
|
||||
SR_CONF_DSO_SYNC,
|
||||
|
||||
/** Zero */
|
||||
SR_CONF_ZERO,
|
||||
|
||||
/** Volts/div. */
|
||||
SR_CONF_VDIV,
|
||||
SR_CONF_VDIV0,
|
||||
SR_CONF_VDIV1,
|
||||
|
||||
/** Coupling. */
|
||||
SR_CONF_COUPLING,
|
||||
SR_CONF_COUPLING0,
|
||||
SR_CONF_COUPLING1,
|
||||
|
||||
/** Channel enable*/
|
||||
SR_CONF_EN_CH0,
|
||||
SR_CONF_EN_CH1,
|
||||
|
||||
/** Trigger types. */
|
||||
SR_CONF_TRIGGER_TYPE,
|
||||
@ -871,7 +886,7 @@ struct sr_session {
|
||||
/** List of struct datafeed_callback pointers. */
|
||||
GSList *datafeed_callbacks;
|
||||
GTimeVal starttime;
|
||||
gboolean running;
|
||||
gboolean running;
|
||||
|
||||
unsigned int num_sources;
|
||||
|
||||
@ -899,6 +914,18 @@ enum {
|
||||
ADV_TRIGGER,
|
||||
};
|
||||
|
||||
enum {
|
||||
DSO_TRIGGER_AUTO = 0,
|
||||
DSO_TRIGGER_CH0,
|
||||
DSO_TRIGGER_CH1,
|
||||
DSO_TRIGGER_CH0A1,
|
||||
DSO_TRIGGER_CH0O1,
|
||||
};
|
||||
enum {
|
||||
DSO_TRIGGER_RISING = 0,
|
||||
DSO_TRIGGER_FALLING,
|
||||
};
|
||||
|
||||
struct ds_trigger {
|
||||
uint16_t trigger_en;
|
||||
uint16_t trigger_mode;
|
||||
|
@ -1,15 +0,0 @@
|
||||
prefix=/usr/local
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/lib
|
||||
includedir=${prefix}/include
|
||||
|
||||
Name: libsigrok4DSLogic
|
||||
Description: Backend library of DSLogic software based on libsigrok
|
||||
URL: http://www.dreamsourcelab.com
|
||||
Requires: glib-2.0
|
||||
Requires.private: libzip libusb-1.0
|
||||
Version: 0.2.0
|
||||
Libs: -L${libdir} -lsigrok4DSLogic
|
||||
Libs.private: -lm
|
||||
Cflags: -I${includedir}
|
||||
|
@ -1,15 +1,15 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: libsigrok4DSLogic
|
||||
Description: Backend library of DSLogic software based on libsigrok
|
||||
URL: http://www.dreamsourcelab.com
|
||||
Requires: glib-2.0
|
||||
Requires.private: @SR_PKGLIBS@
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -lsigrok4DSLogic
|
||||
Libs.private: -lm
|
||||
Cflags: -I${includedir}
|
||||
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: libsigrok4DSLogic
|
||||
Description: Backend library of DSLogic software based on libsigrok
|
||||
URL: http://www.dreamsourcelab.com
|
||||
Requires: glib-2.0
|
||||
Requires.private: @SR_PKGLIBS@
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -lsigrok4DSLogic
|
||||
Libs.private: -lm
|
||||
Cflags: -I${includedir}
|
||||
|
||||
|
@ -1,392 +0,0 @@
|
||||
/*
|
||||
* This file is part of the DSLogic project.
|
||||
*/
|
||||
|
||||
#include "libsigrok.h"
|
||||
#include "hardware/DSLogic/dslogic.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#include <poll.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#endif/*__linux__*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
|
||||
#include <initguid.h>
|
||||
#include <ddk/usbiodef.h>
|
||||
#include <Setupapi.h>
|
||||
|
||||
#include <tchar.h>
|
||||
#include <conio.h>
|
||||
#include <dbt.h>
|
||||
#include <stdio.h>
|
||||
#include <winuser.h>
|
||||
|
||||
#endif/*_WIN32*/
|
||||
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
static void dev_list_add(struct libusbhp_t *h, const char *path,
|
||||
unsigned short vid, unsigned short pid)
|
||||
{
|
||||
struct dev_list_t *dev =
|
||||
(struct dev_list_t*)malloc(sizeof(struct dev_list_t));
|
||||
dev->path = strdup(path);
|
||||
dev->vid = vid;
|
||||
dev->pid = pid;
|
||||
dev->next = NULL;
|
||||
|
||||
struct dev_list_t *p = h->devlist;
|
||||
if(!p) {
|
||||
h->devlist = dev;
|
||||
return;
|
||||
}
|
||||
|
||||
while(p->next) {
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
p->next = dev;
|
||||
}
|
||||
|
||||
static int dev_list_remove(struct libusbhp_t *h, const char *path)
|
||||
{
|
||||
struct dev_list_t *p = h->devlist;
|
||||
if(!p) return 1;
|
||||
|
||||
if(!strcmp(p->path, path)) {
|
||||
h->devlist = p->next;
|
||||
free(p->path);
|
||||
free(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while(p->next) {
|
||||
if(!strcmp(p->next->path, path)) {
|
||||
struct dev_list_t *pp = p->next;
|
||||
p->next = pp->next;
|
||||
free(pp->path);
|
||||
free(pp->next);
|
||||
free(pp);
|
||||
return 0;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
// Not found
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dev_list_find(struct libusbhp_t *h, const char *path,
|
||||
unsigned short *vid, unsigned short *pid)
|
||||
{
|
||||
struct dev_list_t *p = h->devlist;
|
||||
while(p) {
|
||||
if(!strcmp(p->path, path)) {
|
||||
*vid = p->vid;
|
||||
*pid = p->pid;
|
||||
return 0;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
// Not found
|
||||
return 1;
|
||||
}
|
||||
#endif/*__linux__*/
|
||||
|
||||
#ifdef _WIN32
|
||||
SR_PRIV LRESULT CALLBACK WinProcCallback(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
|
||||
{
|
||||
struct libusbhp_t *h = (struct libusbhp_t*)GetWindowLong(hwnd, GWL_USERDATA);
|
||||
|
||||
switch(msg) {
|
||||
case WM_DEVICECHANGE:
|
||||
{
|
||||
PDEV_BROADCAST_HDR phdr = (PDEV_BROADCAST_HDR)lp;
|
||||
|
||||
if(!phdr || phdr->dbch_devicetype != DBT_DEVTYP_DEVICEINTERFACE) break;
|
||||
|
||||
PDEV_BROADCAST_DEVICEINTERFACE devif =
|
||||
(PDEV_BROADCAST_DEVICEINTERFACE)lp;
|
||||
|
||||
HDEVINFO devinfolist = SetupDiCreateDeviceInfoList(NULL, NULL);
|
||||
|
||||
SP_DEVICE_INTERFACE_DATA devifdata;
|
||||
memset(&devifdata, 0, sizeof(devifdata));
|
||||
devifdata.cbSize = sizeof(devifdata);
|
||||
BOOL b = SetupDiOpenDeviceInterface(devinfolist, devif->dbcc_name, 0,
|
||||
&devifdata);
|
||||
|
||||
DWORD required;
|
||||
SP_DEVICE_INTERFACE_DETAIL_DATA devdetaildata;
|
||||
memset(&devdetaildata, 0, sizeof(devdetaildata));
|
||||
devdetaildata.cbSize = sizeof(devdetaildata);
|
||||
|
||||
SP_DEVINFO_DATA devinfodata;
|
||||
memset(&devinfodata, 0, sizeof(devinfodata));
|
||||
devinfodata.cbSize = sizeof(devinfodata);
|
||||
b = SetupDiGetDeviceInterfaceDetail(devinfolist, &devifdata,
|
||||
&devdetaildata,
|
||||
sizeof(devdetaildata),
|
||||
&required, &devinfodata);
|
||||
|
||||
TCHAR deviceidw[1024];
|
||||
b = SetupDiGetDeviceInstanceIdW(devinfolist, &devinfodata, deviceidw,
|
||||
sizeof(deviceidw), NULL);
|
||||
|
||||
char deviceid[1024];
|
||||
//size_t sz;
|
||||
//wcstombs_s(&sz, deviceid, deviceidw, sizeof(deviceid) - 1);
|
||||
wcstombs(deviceid, deviceidw, sizeof(deviceid) - 1);
|
||||
|
||||
char *vid = strstr(deviceid, "VID_");
|
||||
if(vid != NULL) vid += 4;
|
||||
|
||||
char *pid = strstr(deviceid, "PID_");
|
||||
if(pid != NULL) pid += 4;
|
||||
|
||||
struct libusbhp_device_t *device = NULL;
|
||||
|
||||
if(pid || vid) {
|
||||
device =
|
||||
(struct libusbhp_device_t*)malloc(sizeof(struct libusbhp_device_t));
|
||||
}
|
||||
|
||||
if(pid) {
|
||||
pid[4] = '\0';
|
||||
device->idProduct = (unsigned short)strtol(pid, NULL, 16);
|
||||
}
|
||||
|
||||
if(vid) {
|
||||
vid[4] = '\0';
|
||||
device->idVendor = (unsigned short)strtol(vid, NULL, 16);
|
||||
}
|
||||
|
||||
if ((device->idVendor == supported_fx2[0].vid) &&
|
||||
(device->idProduct == supported_fx2[0].pid)) {
|
||||
switch(wp) {
|
||||
case DBT_DEVICEARRIVAL:
|
||||
if(h->attach) h->attach(device, h->user_data);
|
||||
break;
|
||||
case DBT_DEVICEREMOVECOMPLETE:
|
||||
if(h->detach) h->detach(device, h->user_data);
|
||||
break;
|
||||
case DBT_DEVNODES_CHANGED:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(device) free(device);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProc(hwnd, msg, wp, lp);
|
||||
}
|
||||
#endif/*OS_WINDOWS*/
|
||||
|
||||
SR_API int libusbhp_init(struct libusbhp_t **handle)
|
||||
{
|
||||
struct libusbhp_t *h = (struct libusbhp_t *)malloc(sizeof(struct libusbhp_t));
|
||||
|
||||
h->attach = NULL;
|
||||
h->detach = NULL;
|
||||
h->user_data = NULL;
|
||||
|
||||
#ifdef __linux__
|
||||
h->devlist = NULL;
|
||||
|
||||
// create the udev object
|
||||
h->hotplug = udev_new();
|
||||
if(!h->hotplug)
|
||||
{
|
||||
printf("Cannot create udev object\n");
|
||||
free(h);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// create the udev monitor
|
||||
h->hotplug_monitor = udev_monitor_new_from_netlink(h->hotplug, "udev");
|
||||
|
||||
// start receiving hotplug events
|
||||
udev_monitor_filter_add_match_subsystem_devtype(h->hotplug_monitor,
|
||||
"usb", "usb_device");
|
||||
udev_monitor_enable_receiving(h->hotplug_monitor);
|
||||
|
||||
struct udev_enumerate *de = udev_enumerate_new (h->hotplug);
|
||||
udev_enumerate_add_match_subsystem(de, "usb");
|
||||
udev_enumerate_scan_devices(de);
|
||||
|
||||
struct udev_list_entry *lst = udev_enumerate_get_list_entry(de);
|
||||
while(lst) {
|
||||
struct udev_device *dev =
|
||||
udev_device_new_from_syspath(h->hotplug,
|
||||
udev_list_entry_get_name(lst));
|
||||
|
||||
if(udev_device_get_devnode(dev)) {
|
||||
unsigned short idVendor =
|
||||
strtol(udev_device_get_sysattr_value(dev, "idVendor"), NULL, 16);
|
||||
unsigned short idProduct =
|
||||
strtol(udev_device_get_sysattr_value(dev, "idProduct"), NULL, 16);
|
||||
|
||||
dev_list_add(h, udev_device_get_devnode(dev), idVendor, idProduct);
|
||||
}
|
||||
|
||||
udev_device_unref(dev);
|
||||
|
||||
lst = udev_list_entry_get_next(lst);
|
||||
}
|
||||
|
||||
udev_enumerate_unref(de);
|
||||
|
||||
#endif/*__linux__*/
|
||||
|
||||
#ifdef _WIN32
|
||||
memset(&h->wcex, 0, sizeof(h->wcex));
|
||||
h->wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
h->wcex.lpfnWndProc = WinProcCallback;
|
||||
h->wcex.hInstance = GetModuleHandle(NULL);
|
||||
h->wcex.lpszClassName = TEXT("UsbHotplugClass");
|
||||
h->wcex.cbWndExtra = sizeof(struct libusbhp_t*); // Size of data.
|
||||
|
||||
RegisterClassEx(&h->wcex);
|
||||
|
||||
h->hwnd =
|
||||
CreateWindowEx(0, h->wcex.lpszClassName, TEXT("UsbHotplug"), 0, 0, 0, 0,
|
||||
0, 0, NULL, GetModuleHandle(NULL), NULL);
|
||||
|
||||
SetWindowLong(h->hwnd, GWL_USERDATA, (LONG)h);
|
||||
|
||||
|
||||
DEV_BROADCAST_DEVICEINTERFACE *filter =
|
||||
(DEV_BROADCAST_DEVICEINTERFACE*)malloc(sizeof(DEV_BROADCAST_DEVICEINTERFACE));
|
||||
|
||||
memset(filter, 0, sizeof(DEV_BROADCAST_DEVICEINTERFACE));
|
||||
filter->dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
|
||||
filter->dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
|
||||
filter->dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
|
||||
|
||||
h->hDeviceNotify =
|
||||
RegisterDeviceNotification(h->hwnd, filter, DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||
|
||||
if(h->hDeviceNotify == 0) {
|
||||
//printf("RegisterDeviceNotification error\n");
|
||||
free(h);
|
||||
return 1;
|
||||
}
|
||||
#endif/*_WIN32*/
|
||||
|
||||
*handle = h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
SR_API void libusbhp_exit(struct libusbhp_t *h)
|
||||
{
|
||||
#ifdef __linux__
|
||||
// destroy the udev monitor
|
||||
udev_monitor_unref(h->hotplug_monitor);
|
||||
|
||||
// destroy the udev object
|
||||
udev_unref(h->hotplug);
|
||||
#endif/*__linux__*/
|
||||
|
||||
#ifdef _WIN32
|
||||
UnregisterDeviceNotification(h->hDeviceNotify);
|
||||
DestroyWindow(h->hwnd);
|
||||
UnregisterClass(h->wcex.lpszClassName, h->wcex.hInstance);
|
||||
#endif/*_WIN32*/
|
||||
|
||||
free(h);
|
||||
}
|
||||
|
||||
SR_API int libusbhp_handle_events_timeout(struct libusbhp_t *h, struct timeval *tv)
|
||||
{
|
||||
int ms = tv->tv_sec * 1000 + tv->tv_usec / 1000;
|
||||
|
||||
#ifdef __linux__
|
||||
// create the poll item
|
||||
struct pollfd items[1];
|
||||
items[0].fd = udev_monitor_get_fd(h->hotplug_monitor);
|
||||
items[0].events = POLLIN;
|
||||
items[0].revents = 0;
|
||||
|
||||
// while there are hotplug events to process
|
||||
while(poll(items, 1, ms) > 0) {
|
||||
// receive the relevant device
|
||||
struct udev_device* dev = udev_monitor_receive_device(h->hotplug_monitor);
|
||||
if(!dev) {
|
||||
// error receiving device, skip it
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!strcmp(udev_device_get_action(dev), "add")) {
|
||||
struct libusbhp_device_t device;
|
||||
|
||||
device.idVendor =
|
||||
strtol(udev_device_get_sysattr_value(dev, "idVendor"), NULL, 16);
|
||||
device.idProduct =
|
||||
strtol(udev_device_get_sysattr_value(dev, "idProduct"), NULL, 16);
|
||||
|
||||
dev_list_add(h, udev_device_get_devnode(dev),
|
||||
device.idVendor, device.idProduct);
|
||||
|
||||
if(h->attach) h->attach(&device, h->user_data);
|
||||
}
|
||||
|
||||
if(!strcmp(udev_device_get_action(dev), "remove")) {
|
||||
struct libusbhp_device_t device;
|
||||
|
||||
int res = dev_list_find(h, udev_device_get_devnode(dev),
|
||||
&device.idVendor, &device.idProduct);
|
||||
|
||||
if(res) {
|
||||
if(h->detach) h->detach(NULL, h->user_data);
|
||||
} else {
|
||||
dev_list_remove(h, udev_device_get_devnode(dev));
|
||||
if(h->detach) h->detach(&device, h->user_data);
|
||||
}
|
||||
}
|
||||
|
||||
// destroy the relevant device
|
||||
udev_device_unref(dev);
|
||||
|
||||
// clear the revents
|
||||
items[0].revents = 0;
|
||||
}
|
||||
#endif/*__linux__*/
|
||||
|
||||
#ifdef _WIN32
|
||||
UINT_PTR timer = SetTimer(h->hwnd, 0, ms, NULL);
|
||||
|
||||
MSG msg;
|
||||
int ret = GetMessage(&msg, NULL, 0, 0);
|
||||
|
||||
if(ret <= 0) return 0;
|
||||
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
|
||||
KillTimer(h->hwnd, timer);
|
||||
#endif/*_WIN32*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SR_API void libusbhp_register_hotplug_listeners(struct libusbhp_t *handle,
|
||||
libusbhp_hotplug_cb_fn connected_cb,
|
||||
libusbhp_hotplug_cb_fn disconnected_cb,
|
||||
void *user_data)
|
||||
{
|
||||
handle->attach = connected_cb;
|
||||
handle->detach = disconnected_cb;
|
||||
handle->user_data = user_data;
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
/*
|
||||
* This file is part of the libsigrok project.
|
||||
*
|
||||
* Copyright (C) 2010-2012 Bert Vermeulen <bert@biot.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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LIBSIGROK_VERSION_H
|
||||
#define LIBSIGROK_VERSION_H
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* Version number definitions and macros.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup grp_versions
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*
|
||||
* Package version macros (can be used for conditional compilation).
|
||||
*/
|
||||
|
||||
/** The libsigrok package 'major' version number. */
|
||||
#define SR_PACKAGE_VERSION_MAJOR 0
|
||||
|
||||
/** The libsigrok package 'minor' version number. */
|
||||
#define SR_PACKAGE_VERSION_MINOR 2
|
||||
|
||||
/** The libsigrok package 'micro' version number. */
|
||||
#define SR_PACKAGE_VERSION_MICRO 0
|
||||
|
||||
/** The libsigrok package version ("major.minor.micro") as string. */
|
||||
#define SR_PACKAGE_VERSION_STRING "0.2.0"
|
||||
|
||||
/*
|
||||
* Library/libtool version macros (can be used for conditional compilation).
|
||||
*/
|
||||
|
||||
/** The libsigrok libtool 'current' version number. */
|
||||
#define SR_LIB_VERSION_CURRENT 1
|
||||
|
||||
/** The libsigrok libtool 'revision' version number. */
|
||||
#define SR_LIB_VERSION_REVISION 2
|
||||
|
||||
/** The libsigrok libtool 'age' version number. */
|
||||
#define SR_LIB_VERSION_AGE 0
|
||||
|
||||
/** The libsigrok libtool version ("current:revision:age") as string. */
|
||||
#define SR_LIB_VERSION_STRING "1:2:0"
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user