summaryrefslogtreecommitdiff
path: root/DSLogic-gui
diff options
context:
space:
mode:
authorSven Wegener <sven.wegener@stealer.net>2014-06-30 09:38:31 +0200
committerSven Wegener <sven.wegener@stealer.net>2014-06-30 09:38:31 +0200
commit79de83205964ee0182940ef7cec86b46896ed0e6 (patch)
treeccf532205a550ac926e52069649a1cc41aa555a6 /DSLogic-gui
parent3de7dbb24c71c0d894dbd734ddf9258683d9e2e1 (diff)
Update from DSLogic-v0.3.tar.gzHEADmaster
Signed-off-by: Sven Wegener <sven.wegener@stealer.net>
Diffstat (limited to 'DSLogic-gui')
-rw-r--r--DSLogic-gui/CMakeLists.txt30
-rw-r--r--DSLogic-gui/DSLogic.qrc2
-rw-r--r--DSLogic-gui/INSTALL98
-rw-r--r--DSLogic-gui/NEWS10
-rw-r--r--DSLogic-gui/extdef.h5
-rw-r--r--DSLogic-gui/icons/checkbox.pngbin0 -> 243 bytes
-rw-r--r--DSLogic-gui/icons/radiobutton.pngbin0 -> 241 bytes
-rw-r--r--DSLogic-gui/icons/╕─╝■ down-arrow.png (renamed from DSLogic-gui/icons/©¦+¦ down-arrow.png)bin150 -> 150 bytes
-rw-r--r--DSLogic-gui/icons/╕─╝■ params.png (renamed from DSLogic-gui/icons/©¦+¦ params.png)bin2806 -> 2806 bytes
-rw-r--r--DSLogic-gui/main.cpp22
-rw-r--r--DSLogic-gui/pv/data/analog.cpp4
-rw-r--r--DSLogic-gui/pv/data/analogsnapshot.cpp10
-rw-r--r--DSLogic-gui/pv/data/dso.cpp48
-rw-r--r--DSLogic-gui/pv/data/dso.h54
-rw-r--r--DSLogic-gui/pv/data/dsosnapshot.cpp232
-rw-r--r--DSLogic-gui/pv/data/dsosnapshot.h97
-rw-r--r--DSLogic-gui/pv/data/group.cpp4
-rw-r--r--DSLogic-gui/pv/data/groupsnapshot.cpp14
-rw-r--r--DSLogic-gui/pv/data/logic.cpp4
-rw-r--r--DSLogic-gui/pv/data/logicsnapshot.cpp14
-rw-r--r--DSLogic-gui/pv/data/snapshot.cpp14
-rw-r--r--DSLogic-gui/pv/decoder/ds1wire.cpp10
-rw-r--r--DSLogic-gui/pv/decoder/dsdmx512.cpp10
-rw-r--r--DSLogic-gui/pv/decoder/dsi2c.cpp12
-rw-r--r--DSLogic-gui/pv/decoder/dsserial.cpp16
-rw-r--r--DSLogic-gui/pv/decoder/dsspi.cpp12
-rw-r--r--DSLogic-gui/pv/devicemanager.cpp12
-rw-r--r--DSLogic-gui/pv/dialogs/deviceoptions.cpp24
-rw-r--r--DSLogic-gui/pv/dialogs/deviceoptions.h2
-rw-r--r--DSLogic-gui/pv/dialogs/search.cpp42
-rw-r--r--DSLogic-gui/pv/dialogs/search.h10
-rw-r--r--DSLogic-gui/pv/dock/dsotriggerdock.cpp196
-rw-r--r--DSLogic-gui/pv/dock/dsotriggerdock.h76
-rw-r--r--DSLogic-gui/pv/dock/measuredock.cpp2
-rw-r--r--DSLogic-gui/pv/dock/triggerdock.cpp24
-rw-r--r--DSLogic-gui/pv/mainwindow.cpp123
-rw-r--r--DSLogic-gui/pv/mainwindow.h10
-rw-r--r--DSLogic-gui/pv/prop/binding/binding_deviceoptions.cpp24
-rw-r--r--DSLogic-gui/pv/sigsession.cpp731
-rw-r--r--DSLogic-gui/pv/sigsession.h48
-rw-r--r--DSLogic-gui/pv/toolbars/devicebar.cpp17
-rw-r--r--DSLogic-gui/pv/toolbars/devicebar.h1
-rw-r--r--DSLogic-gui/pv/toolbars/samplingbar.cpp91
-rw-r--r--DSLogic-gui/pv/toolbars/samplingbar.h3
-rw-r--r--DSLogic-gui/pv/view/analogsignal.cpp12
-rw-r--r--DSLogic-gui/pv/view/analogsignal.h1
-rw-r--r--DSLogic-gui/pv/view/dsldial.cpp110
-rw-r--r--DSLogic-gui/pv/view/dsldial.h48
-rw-r--r--DSLogic-gui/pv/view/dsosignal.cpp224
-rw-r--r--DSLogic-gui/pv/view/dsosignal.h103
-rw-r--r--DSLogic-gui/pv/view/groupsignal.cpp12
-rw-r--r--DSLogic-gui/pv/view/groupsignal.h1
-rw-r--r--DSLogic-gui/pv/view/header.cpp240
-rw-r--r--DSLogic-gui/pv/view/header.h21
-rw-r--r--DSLogic-gui/pv/view/logicsignal.cpp8
-rw-r--r--DSLogic-gui/pv/view/logicsignal.h1
-rw-r--r--DSLogic-gui/pv/view/protocolsignal.cpp9
-rw-r--r--DSLogic-gui/pv/view/protocolsignal.h1
-rw-r--r--DSLogic-gui/pv/view/ruler.cpp6
-rw-r--r--DSLogic-gui/pv/view/signal.cpp498
-rw-r--r--DSLogic-gui/pv/view/signal.h112
-rw-r--r--DSLogic-gui/pv/view/view.cpp95
-rw-r--r--DSLogic-gui/pv/view/view.h7
-rw-r--r--DSLogic-gui/pv/view/viewport.cpp129
-rw-r--r--DSLogic-gui/pv/view/viewport.h9
-rw-r--r--DSLogic-gui/res/DSLogic.binbin0 -> 340884 bytes
-rw-r--r--DSLogic-gui/res/DSLogic.fwbin0 -> 8120 bytes
-rw-r--r--DSLogic-gui/stylesheet.qss27
-rw-r--r--DSLogic-gui/test/CMakeLists.txt287
-rw-r--r--DSLogic-gui/test/COPYING674
-rw-r--r--DSLogic-gui/test/DSLogic.qrc33
-rw-r--r--DSLogic-gui/test/INSTALL49
-rw-r--r--DSLogic-gui/test/NEWS5
-rw-r--r--DSLogic-gui/test/README72
-rw-r--r--DSLogic-gui/test/config.h.in (renamed from DSLogic-gui/config.h)14
-rw-r--r--DSLogic-gui/test/extdef.h32
-rw-r--r--DSLogic-gui/test/main.cpp163
-rw-r--r--DSLogic-gui/test/stylesheet.qss279
78 files changed, 4748 insertions, 692 deletions
diff --git a/DSLogic-gui/CMakeLists.txt b/DSLogic-gui/CMakeLists.txt
index 5a4fb8f..539ab0d 100644
--- a/DSLogic-gui/CMakeLists.txt
+++ b/DSLogic-gui/CMakeLists.txt
@@ -3,6 +3,7 @@
##
## Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
## 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
@@ -22,13 +23,13 @@ cmake_minimum_required(VERSION 2.6)
include(FindPkgConfig)
include(GNUInstallDirs)
-project(DSLogic-gui)
+project(DSLogic)
#===============================================================================
#= User Options
#-------------------------------------------------------------------------------
-option(DISABLE_WERROR "Build without -Werror" FALSE)
+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)
@@ -52,8 +53,11 @@ endif()
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})
@@ -71,6 +75,8 @@ else()
find_package(Boost 1.42 COMPONENTS system thread REQUIRED)
endif()
+find_package(libusb-1.0 REQUIRED)
+
#===============================================================================
#= Config Header
#-------------------------------------------------------------------------------
@@ -79,7 +85,7 @@ set(DS_TITLE DSLogic)
set(DS_DESCRIPTION "A GUI for DSLogic")
set(DS_VERSION_MAJOR 0)
-set(DS_VERSION_MINOR 1)
+set(DS_VERSION_MINOR 3)
set(DS_VERSION_MICRO 0)
set(DS_VERSION_STRING
${DS_VERSION_MAJOR}.${DS_VERSION_MINOR}.${DS_VERSION_MICRO}
@@ -107,6 +113,8 @@ set(DSLogic_SOURCES
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
@@ -147,6 +155,9 @@ set(DSLogic_SOURCES
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
@@ -167,6 +178,8 @@ set(DSLogic_HEADERS
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
@@ -174,12 +187,14 @@ set(DSLogic_HEADERS
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/dialogs/search.ui
pv/decoder/dmx512config.ui
pv/decoder/i2cconfig.ui
pv/decoder/serialconfig.ui
@@ -234,6 +249,7 @@ set(DSLOGIC_LINK_LIBS
${Boost_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
${QT_LIBRARIES}
+ ${LIBUSB_1_LIBRARIES}
)
if(STATIC_PKGDEPS_LIBS)
@@ -257,6 +273,7 @@ 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
@@ -264,9 +281,8 @@ endif()
# Install the executable.
install(TARGETS ${PROJECT_NAME} DESTINATION bin/)
-
-# Install the manpage.
-install(FILES doc/DSLogic.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 COMPONENT doc)
+install(FILES res/DSLogic.fw DESTINATION bin/res/)
+install(FILES res/DSLogic.bin DESTINATION bin/res/)
#===============================================================================
#= Packaging (handled by CPack)
diff --git a/DSLogic-gui/DSLogic.qrc b/DSLogic-gui/DSLogic.qrc
index 8162e2d..d7b5e8a 100644
--- a/DSLogic-gui/DSLogic.qrc
+++ b/DSLogic-gui/DSLogic.qrc
@@ -27,5 +27,7 @@
<file>icons/start.png</file>
<file>icons/dsl_logo.png</file>
<file>icons/logo.png</file>
+ <file>icons/checkbox.png</file>
+ <file>icons/radiobutton.png</file>
</qresource>
</RCC>
diff --git a/DSLogic-gui/INSTALL b/DSLogic-gui/INSTALL
index 4032ead..126579b 100644
--- a/DSLogic-gui/INSTALL
+++ b/DSLogic-gui/INSTALL
@@ -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
+
diff --git a/DSLogic-gui/NEWS b/DSLogic-gui/NEWS
index dbbe970..e7c2c79 100644
--- a/DSLogic-gui/NEWS
+++ b/DSLogic-gui/NEWS
@@ -1,5 +1,5 @@
-0.1.0 (2013-12-15)
-------------------
-
- * Initial release.
-
+0.1.0 (2013-12-15)
+------------------
+
+ * Initial release.
+
diff --git a/DSLogic-gui/extdef.h b/DSLogic-gui/extdef.h
index 29ea8f5..467b561 100644
--- a/DSLogic-gui/extdef.h
+++ b/DSLogic-gui/extdef.h
@@ -1,7 +1,9 @@
/*
- * This file is part of the PulseView project.
+ * 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
@@ -18,6 +20,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+
#ifndef DSLOGIC_EXTDEF_H
#define DSLOGIC_EXTDEF_H
diff --git a/DSLogic-gui/icons/checkbox.png b/DSLogic-gui/icons/checkbox.png
new file mode 100644
index 0000000..8ca5395
--- /dev/null
+++ b/DSLogic-gui/icons/checkbox.png
Binary files differ
diff --git a/DSLogic-gui/icons/radiobutton.png b/DSLogic-gui/icons/radiobutton.png
new file mode 100644
index 0000000..85fe185
--- /dev/null
+++ b/DSLogic-gui/icons/radiobutton.png
Binary files differ
diff --git a/DSLogic-gui/icons/©¦+¦ down-arrow.png b/DSLogic-gui/icons/╕─╝■ down-arrow.png
index 602c191..602c191 100644
--- a/DSLogic-gui/icons/©¦+¦ down-arrow.png
+++ b/DSLogic-gui/icons/╕─╝■ down-arrow.png
Binary files differ
diff --git a/DSLogic-gui/icons/©¦+¦ params.png b/DSLogic-gui/icons/╕─╝■ params.png
index 8c4b2c8..8c4b2c8 100644
--- a/DSLogic-gui/icons/©¦+¦ params.png
+++ b/DSLogic-gui/icons/╕─╝■ params.png
Binary files differ
diff --git a/DSLogic-gui/main.cpp b/DSLogic-gui/main.cpp
index 04772d4..807f3ce 100644
--- a/DSLogic-gui/main.cpp
+++ b/DSLogic-gui/main.cpp
@@ -1,7 +1,9 @@
/*
- * This file is part of the PulseView project.
+ * 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
@@ -18,6 +20,7 @@
* 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
@@ -58,9 +61,9 @@ int main(int argc, char *argv[])
QApplication a(argc, argv);
// Set some application metadata
- QApplication::setApplicationVersion(DS_VERSION_STRING);
- QApplication::setApplicationName("DSLogic");
- QApplication::setOrganizationDomain("http://www.DreamSourceLab.com");
+ QApplication::setApplicationVersion(DS_VERSION_STRING);
+ QApplication::setApplicationName("DSLogic(Beta)");
+ QApplication::setOrganizationDomain("http://www.DreamSourceLab.com");
// Parse arguments
while (1) {
@@ -131,12 +134,11 @@ int main(int argc, char *argv[])
pv::DeviceManager device_manager(sr_ctx);
// Initialise the main window
- pv::MainWindow w(device_manager, open_file);
- //QFile qss(":/levelfour.qss");
- QFile qss(":/stylesheet.qss");
- qss.open(QFile::ReadOnly);
- a.setStyleSheet(qss.readAll());
- qss.close();
+ 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
diff --git a/DSLogic-gui/pv/data/analog.cpp b/DSLogic-gui/pv/data/analog.cpp
index a62e288..d4e6304 100644
--- a/DSLogic-gui/pv/data/analog.cpp
+++ b/DSLogic-gui/pv/data/analog.cpp
@@ -35,12 +35,12 @@ Analog::Analog(unsigned int num_probes, uint64_t samplerate) :
{
}
-void Analog::push_snapshot(shared_ptr<AnalogSnapshot> &snapshot)
+void Analog::push_snapshot(boost::shared_ptr<AnalogSnapshot> &snapshot)
{
_snapshots.push_front(snapshot);
}
-deque< shared_ptr<AnalogSnapshot> >& Analog::get_snapshots()
+deque< boost::shared_ptr<AnalogSnapshot> >& Analog::get_snapshots()
{
return _snapshots;
}
diff --git a/DSLogic-gui/pv/data/analogsnapshot.cpp b/DSLogic-gui/pv/data/analogsnapshot.cpp
index 3ff8e80..f613983 100644
--- a/DSLogic-gui/pv/data/analogsnapshot.cpp
+++ b/DSLogic-gui/pv/data/analogsnapshot.cpp
@@ -49,7 +49,7 @@ const uint64_t AnalogSnapshot::EnvelopeDataUnit = 64*1024; // bytes
AnalogSnapshot::AnalogSnapshot(const sr_datafeed_analog &analog, uint64_t _total_sample_len, unsigned int channel_num) :
Snapshot(sizeof(uint16_t), _total_sample_len, channel_num)
{
- lock_guard<recursive_mutex> lock(_mutex);
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
memset(_envelope_levels, 0, sizeof(_envelope_levels));
init(_total_sample_len * channel_num);
append_payload(analog);
@@ -57,7 +57,7 @@ AnalogSnapshot::AnalogSnapshot(const sr_datafeed_analog &analog, uint64_t _total
AnalogSnapshot::~AnalogSnapshot()
{
- lock_guard<recursive_mutex> lock(_mutex);
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
BOOST_FOREACH(Envelope &e, _envelope_levels[0])
free(e.samples);
}
@@ -65,7 +65,7 @@ AnalogSnapshot::~AnalogSnapshot()
void AnalogSnapshot::append_payload(
const sr_datafeed_analog &analog)
{
- lock_guard<recursive_mutex> lock(_mutex);
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
append_data(analog.data, analog.num_samples);
// Generate the first mip-map from the data
@@ -81,7 +81,7 @@ const uint16_t* AnalogSnapshot::get_samples(
assert(end_sample < (int64_t)get_sample_count());
assert(start_sample <= end_sample);
- lock_guard<recursive_mutex> lock(_mutex);
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
// uint16_t *const data = new uint16_t[end_sample - start_sample];
// memcpy(data, (uint16_t*)_data + start_sample, sizeof(uint16_t) *
@@ -97,7 +97,7 @@ void AnalogSnapshot::get_envelope_section(EnvelopeSection &s,
assert(start <= end);
assert(min_length > 0);
- lock_guard<recursive_mutex> lock(_mutex);
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
const unsigned int min_level = max((int)floorf(logf(min_length) /
LogEnvelopeScaleFactor) - 1, 0);
diff --git a/DSLogic-gui/pv/data/dso.cpp b/DSLogic-gui/pv/data/dso.cpp
new file mode 100644
index 0000000..fc967ff
--- /dev/null
+++ b/DSLogic-gui/pv/data/dso.cpp
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the DSLogic-gui project.
+ * DSLogic-gui is based on PulseView.
+ *
+ * Copyright (C) 2013 DreamSourceLab <dreamsourcelab@dreamsourcelab.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#include "dso.h"
+#include "dsosnapshot.h"
+
+using namespace boost;
+using namespace std;
+
+namespace pv {
+namespace data {
+
+Dso::Dso(unsigned int num_probes, uint64_t samplerate) :
+ SignalData(num_probes, samplerate)
+{
+}
+
+void Dso::push_snapshot(boost::shared_ptr<DsoSnapshot> &snapshot)
+{
+ _snapshots.push_front(snapshot);
+}
+
+deque< boost::shared_ptr<DsoSnapshot> >& Dso::get_snapshots()
+{
+ return _snapshots;
+}
+
+} // namespace data
+} // namespace pv
diff --git a/DSLogic-gui/pv/data/dso.h b/DSLogic-gui/pv/data/dso.h
new file mode 100644
index 0000000..591fa27
--- /dev/null
+++ b/DSLogic-gui/pv/data/dso.h
@@ -0,0 +1,54 @@
+/*
+ * This file is part of the DSLogic-gui project.
+ * DSLogic-gui is based on PulseView.
+ *
+ * Copyright (C) 2013 DreamSourceLab <dreamsourcelab@dreamsourcelab.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#ifndef DSLOGIC_PV_DATA_DSO_H
+#define DSLOGIC_PV_DATA_DSO_H
+
+#include "signaldata.h"
+
+#include <boost/shared_ptr.hpp>
+#include <deque>
+
+namespace pv {
+namespace data {
+
+class DsoSnapshot;
+
+class Dso : public SignalData
+{
+public:
+ Dso(unsigned int num_probes, uint64_t samplerate);
+
+ void push_snapshot(
+ boost::shared_ptr<DsoSnapshot> &snapshot);
+
+ std::deque< boost::shared_ptr<DsoSnapshot> >&
+ get_snapshots();
+
+private:
+ std::deque< boost::shared_ptr<DsoSnapshot> > _snapshots;
+};
+
+} // namespace data
+} // namespace pv
+
+#endif // DSLOGIC_PV_DATA_DSO_H
diff --git a/DSLogic-gui/pv/data/dsosnapshot.cpp b/DSLogic-gui/pv/data/dsosnapshot.cpp
new file mode 100644
index 0000000..fb05e5d
--- /dev/null
+++ b/DSLogic-gui/pv/data/dsosnapshot.cpp
@@ -0,0 +1,232 @@
+/*
+ * This file is part of the DSLogic-gui project.
+ * DSLogic-gui is based on PulseView.
+ *
+ * Copyright (C) 2013 DreamSourceLab <dreamsourcelab@dreamsourcelab.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#include <extdef.h>
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include <algorithm>
+
+#include <boost/foreach.hpp>
+
+#include "dsosnapshot.h"
+
+using namespace boost;
+using namespace std;
+
+namespace pv {
+namespace data {
+
+const int DsoSnapshot::EnvelopeScalePower = 4;
+const int DsoSnapshot::EnvelopeScaleFactor = 1 << EnvelopeScalePower;
+const float DsoSnapshot::LogEnvelopeScaleFactor =
+ logf(EnvelopeScaleFactor);
+const uint64_t DsoSnapshot::EnvelopeDataUnit = 64*1024; // bytes
+
+DsoSnapshot::DsoSnapshot(const sr_datafeed_dso &dso, uint64_t _total_sample_len, unsigned int channel_num) :
+ Snapshot(sizeof(uint16_t), _total_sample_len, channel_num)
+{
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
+ memset(_envelope_levels, 0, sizeof(_envelope_levels));
+ init(_total_sample_len * channel_num);
+ append_payload(dso);
+}
+
+DsoSnapshot::~DsoSnapshot()
+{
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
+ BOOST_FOREACH(Envelope &e, _envelope_levels[0])
+ free(e.samples);
+}
+
+void DsoSnapshot::append_payload(const sr_datafeed_dso &dso)
+{
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
+ append_data(dso.data, dso.num_samples);
+
+ // Generate the first mip-map from the data
+ append_payload_to_envelope_levels();
+}
+
+const 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());
+ assert(end_sample >= 0);
+ assert(end_sample < (int64_t)get_sample_count());
+ assert(start_sample <= end_sample);
+
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
+
+// uint16_t *const data = new uint16_t[end_sample - start_sample];
+// memcpy(data, (uint16_t*)_data + start_sample, sizeof(uint16_t) *
+// (end_sample - start_sample));
+// return data;
+ return (uint8_t*)_data + start_sample * _channel_num + index;
+}
+
+void DsoSnapshot::get_envelope_section(EnvelopeSection &s,
+ uint64_t start, uint64_t end, float min_length, int probe_index) const
+{
+ assert(end <= get_sample_count());
+ assert(start <= end);
+ assert(min_length > 0);
+
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
+
+ const unsigned int min_level = max((int)floorf(logf(min_length) /
+ LogEnvelopeScaleFactor) - 1, 0);
+ const unsigned int scale_power = (min_level + 1) *
+ EnvelopeScalePower;
+ start >>= scale_power;
+ end >>= scale_power;
+
+ s.start = start << scale_power;
+ s.scale = 1 << scale_power;
+ s.length = end - start;
+// s.samples = new EnvelopeSample[s.length];
+// memcpy(s.samples, _envelope_levels[min_level].samples + start,
+// s.length * sizeof(EnvelopeSample));
+ s.samples = _envelope_levels[probe_index][min_level].samples + start;
+}
+
+void DsoSnapshot::reallocate_envelope(Envelope &e)
+{
+ const uint64_t new_data_length = ((e.length + EnvelopeDataUnit - 1) /
+ EnvelopeDataUnit) * EnvelopeDataUnit;
+ if (new_data_length > e.data_length)
+ {
+ e.data_length = new_data_length;
+ e.samples = (EnvelopeSample*)realloc(e.samples,
+ new_data_length * sizeof(EnvelopeSample));
+ }
+}
+
+void DsoSnapshot::append_payload_to_envelope_levels()
+{
+ unsigned int i;
+ for (i = 0; i < _channel_num; i++) {
+ Envelope &e0 = _envelope_levels[i][0];
+ uint64_t prev_length;
+ EnvelopeSample *dest_ptr;
+
+ // Expand the data buffer to fit the new samples
+ prev_length = e0.length;
+ e0.length = get_sample_count() / EnvelopeScaleFactor;
+
+ // Break off if there are no new samples to compute
+ // if (e0.length == prev_length)
+ // return;
+ if (e0.length == 0)
+ return;
+ if (e0.length == prev_length)
+ prev_length = 0;
+
+ reallocate_envelope(e0);
+
+ dest_ptr = e0.samples + prev_length;
+
+ // Iterate through the samples to populate the first level mipmap
+ const 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;
+// src_ptr < end_src_ptr; src_ptr += EnvelopeScaleFactor)
+// {
+// const EnvelopeSample sub_sample = {
+// *min_element(src_ptr, src_ptr + EnvelopeScaleFactor),
+// *max_element(src_ptr, src_ptr + EnvelopeScaleFactor),
+// };
+
+// *dest_ptr++ = sub_sample;
+// }
+ for (const uint8_t *src_ptr = (uint8_t*)_data +
+ prev_length * EnvelopeScaleFactor * _channel_num + i;
+ src_ptr < stop_src_ptr; src_ptr += EnvelopeScaleFactor * _channel_num)
+ {
+ const uint8_t * begin_src_ptr =
+ src_ptr;
+ const uint8_t *const end_src_ptr =
+ src_ptr + EnvelopeScaleFactor * _channel_num;
+
+ EnvelopeSample sub_sample;
+ sub_sample.min = *begin_src_ptr;
+ sub_sample.max = *begin_src_ptr;
+ begin_src_ptr += _channel_num;
+ while (begin_src_ptr < end_src_ptr)
+ {
+ sub_sample.min = min(sub_sample.min, *begin_src_ptr);
+ sub_sample.max = max(sub_sample.max, *begin_src_ptr);
+ begin_src_ptr += _channel_num;
+ }
+
+ *dest_ptr++ = sub_sample;
+ }
+
+ // Compute higher level mipmaps
+ for (unsigned int level = 1; level < ScaleStepCount; level++)
+ {
+ Envelope &e = _envelope_levels[i][level];
+ const Envelope &el = _envelope_levels[i][level-1];
+
+ // Expand the data buffer to fit the new samples
+ prev_length = e.length;
+ e.length = el.length / EnvelopeScaleFactor;
+
+ // Break off if there are no more samples to computed
+ // if (e.length == prev_length)
+ // break;
+ if (e.length == prev_length)
+ prev_length = 0;
+
+ reallocate_envelope(e);
+
+ // Subsample the level lower level
+ const EnvelopeSample *src_ptr =
+ el.samples + prev_length * EnvelopeScaleFactor;
+ const EnvelopeSample *const end_dest_ptr = e.samples + e.length;
+ for (dest_ptr = e.samples + prev_length;
+ dest_ptr < end_dest_ptr; dest_ptr++)
+ {
+ const EnvelopeSample *const end_src_ptr =
+ src_ptr + EnvelopeScaleFactor;
+
+ EnvelopeSample sub_sample = *src_ptr++;
+ while (src_ptr < end_src_ptr)
+ {
+ sub_sample.min = min(sub_sample.min, src_ptr->min);
+ sub_sample.max = max(sub_sample.max, src_ptr->max);
+ src_ptr++;
+ }
+
+ *dest_ptr = sub_sample;
+ }
+ }
+ }
+}
+
+} // namespace data
+} // namespace pv
diff --git a/DSLogic-gui/pv/data/dsosnapshot.h b/DSLogic-gui/pv/data/dsosnapshot.h
new file mode 100644
index 0000000..155dd72
--- /dev/null
+++ b/DSLogic-gui/pv/data/dsosnapshot.h
@@ -0,0 +1,97 @@
+/*
+ * This file is part of the DSLogic-gui project.
+ * DSLogic-gui is based on PulseView.
+ *
+ * Copyright (C) 2013 DreamSourceLab <dreamsourcelab@dreamsourcelab.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#ifndef DSLOGIC_PV_DATA_DSOSNAPSHOT_H
+#define DSLOGIC_PV_DATA_DSOSNAPSHOT_H
+
+#include "snapshot.h"
+
+#include <utility>
+#include <vector>
+
+namespace DsoSnapshotTest {
+class Basic;
+}
+
+namespace pv {
+namespace data {
+
+class DsoSnapshot : public Snapshot
+{
+public:
+ struct EnvelopeSample
+ {
+ uint8_t min;
+ uint8_t max;
+ };
+
+ struct EnvelopeSection
+ {
+ uint64_t start;
+ unsigned int scale;
+ uint64_t length;
+ EnvelopeSample *samples;
+ };
+
+private:
+ struct Envelope
+ {
+ uint64_t length;
+ uint64_t data_length;
+ EnvelopeSample *samples;
+ };
+
+private:
+ static const unsigned int ScaleStepCount = 10;
+ static const int EnvelopeScalePower;
+ static const int EnvelopeScaleFactor;
+ static const float LogEnvelopeScaleFactor;
+ static const uint64_t EnvelopeDataUnit;
+
+public:
+ DsoSnapshot(const sr_datafeed_dso &dso, uint64_t _total_sample_len, unsigned int channel_num);
+
+ virtual ~DsoSnapshot();
+
+ void append_payload(const sr_datafeed_dso &dso);
+
+ const 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;
+
+private:
+ void reallocate_envelope(Envelope &l);
+
+ void append_payload_to_envelope_levels();
+
+private:
+ struct Envelope _envelope_levels[2*DS_MAX_DSO_PROBES_NUM][ScaleStepCount];
+
+ friend class DsoSnapshotTest::Basic;
+};
+
+} // namespace data
+} // namespace pv
+
+#endif // DSLOGIC_PV_DATA_DSOSNAPSHOT_H
diff --git a/DSLogic-gui/pv/data/group.cpp b/DSLogic-gui/pv/data/group.cpp
index 26cccd7..6df3ee8 100644
--- a/DSLogic-gui/pv/data/group.cpp
+++ b/DSLogic-gui/pv/data/group.cpp
@@ -35,12 +35,12 @@ Group::Group(unsigned int num_probes, uint64_t samplerate) :
{
}
-void Group::push_snapshot(shared_ptr<GroupSnapshot> &snapshot)
+void Group::push_snapshot(boost::shared_ptr<GroupSnapshot> &snapshot)
{
_snapshots.push_back(snapshot);
}
-deque< shared_ptr<GroupSnapshot> >& Group::get_snapshots()
+deque< boost::shared_ptr<GroupSnapshot> >& Group::get_snapshots()
{
return _snapshots;
}
diff --git a/DSLogic-gui/pv/data/groupsnapshot.cpp b/DSLogic-gui/pv/data/groupsnapshot.cpp
index d46da5b..939ffca 100644
--- a/DSLogic-gui/pv/data/groupsnapshot.cpp
+++ b/DSLogic-gui/pv/data/groupsnapshot.cpp
@@ -51,11 +51,11 @@ const uint16_t GroupSnapshot::value_mask[16] = {0x1, 0x2, 0x4, 0x8,
0x100, 0x200, 0x400, 0x800,
0x1000, 0x2000, 0x4000, 0x8000};
-GroupSnapshot::GroupSnapshot(const shared_ptr<LogicSnapshot> &_logic_snapshot, std::list<int> index_list)
+GroupSnapshot::GroupSnapshot(const boost::shared_ptr<LogicSnapshot> &_logic_snapshot, std::list<int> index_list)
{
assert(_logic_snapshot);
- lock_guard<recursive_mutex> lock(_mutex);
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
memset(_envelope_levels, 0, sizeof(_envelope_levels));
_data = _logic_snapshot->get_data();
_sample_count = _logic_snapshot->get_sample_count();
@@ -66,20 +66,20 @@ GroupSnapshot::GroupSnapshot(const shared_ptr<LogicSnapshot> &_logic_snapshot, s
GroupSnapshot::~GroupSnapshot()
{
- lock_guard<recursive_mutex> lock(_mutex);
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
BOOST_FOREACH(Envelope &e, _envelope_levels)
free(e.samples);
}
uint64_t GroupSnapshot::get_sample_count() const
{
- lock_guard<recursive_mutex> lock(_mutex);
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
return _sample_count;
}
void GroupSnapshot::append_payload()
{
- lock_guard<recursive_mutex> lock(_mutex);
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
// Generate the first mip-map from the data
append_payload_to_envelope_levels();
@@ -96,7 +96,7 @@ const uint16_t* GroupSnapshot::get_samples(
int64_t i;
uint64_t pow;
- lock_guard<recursive_mutex> lock(_mutex);
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
uint16_t *const data = new uint16_t[end_sample - start_sample];
// memcpy(data, (uint16_t*)_data + start_sample, sizeof(uint16_t) *
@@ -121,7 +121,7 @@ void GroupSnapshot::get_envelope_section(EnvelopeSection &s,
assert(start <= end);
assert(min_length > 0);
- lock_guard<recursive_mutex> lock(_mutex);
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
const unsigned int min_level = max((int)floorf(logf(min_length) /
LogEnvelopeScaleFactor) - 1, 0);
diff --git a/DSLogic-gui/pv/data/logic.cpp b/DSLogic-gui/pv/data/logic.cpp
index 036cc54..4cdfe2a 100644
--- a/DSLogic-gui/pv/data/logic.cpp
+++ b/DSLogic-gui/pv/data/logic.cpp
@@ -37,12 +37,12 @@ Logic::Logic(unsigned int num_probes, uint64_t samplerate) :
}
void Logic::push_snapshot(
- shared_ptr<LogicSnapshot> &snapshot)
+ boost::shared_ptr<LogicSnapshot> &snapshot)
{
_snapshots.push_front(snapshot);
}
-deque< shared_ptr<LogicSnapshot> >& Logic::get_snapshots()
+deque< boost::shared_ptr<LogicSnapshot> >& Logic::get_snapshots()
{
return _snapshots;
}
diff --git a/DSLogic-gui/pv/data/logicsnapshot.cpp b/DSLogic-gui/pv/data/logicsnapshot.cpp
index e01386a..9a6b2d2 100644
--- a/DSLogic-gui/pv/data/logicsnapshot.cpp
+++ b/DSLogic-gui/pv/data/logicsnapshot.cpp
@@ -47,7 +47,7 @@ LogicSnapshot::LogicSnapshot(const sr_datafeed_logic &logic, uint64_t _total_sam
Snapshot(logic.unitsize, _total_sample_len, channel_num),
_last_append_sample(0)
{
- lock_guard<recursive_mutex> lock(_mutex);
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
memset(_mip_map, 0, sizeof(_mip_map));
if (init(_total_sample_len * channel_num) == SR_OK)
append_payload(logic);
@@ -55,7 +55,7 @@ LogicSnapshot::LogicSnapshot(const sr_datafeed_logic &logic, uint64_t _total_sam
LogicSnapshot::~LogicSnapshot()
{
- lock_guard<recursive_mutex> lock(_mutex);
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
BOOST_FOREACH(MipMapLevel &l, _mip_map)
free(l.data);
}
@@ -66,7 +66,7 @@ void LogicSnapshot::append_payload(
assert(_unit_size == logic.unitsize);
assert((logic.length % _unit_size) == 0);
- lock_guard<recursive_mutex> lock(_mutex);
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
append_data(logic.data, logic.length / _unit_size);
@@ -194,7 +194,7 @@ void LogicSnapshot::get_subsampled_edges(
assert(sig_index >= 0);
assert(sig_index < 64);
- lock_guard<recursive_mutex> lock(_mutex);
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
const uint64_t block_length = (uint64_t)max(min_length, 1.0f);
const unsigned int min_level = max((int)floorf(logf(min_length) /
@@ -378,7 +378,7 @@ int LogicSnapshot::get_first_edge(
assert(sig_index >= 0);
assert(sig_index < 64);
- lock_guard<recursive_mutex> lock(_mutex);
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
const uint64_t block_length = 1;
const unsigned int min_level = 0;
@@ -550,7 +550,7 @@ void LogicSnapshot::get_edges(
assert(sig_index >= 0);
assert(sig_index < 64);
- lock_guard<recursive_mutex> lock(_mutex);
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
const uint64_t block_length = 1;
const unsigned int min_level = 0;
@@ -706,7 +706,7 @@ uint64_t LogicSnapshot::get_min_pulse(uint64_t start, uint64_t end, int sig_inde
assert(sig_index >= 0);
assert(sig_index < 64);
- lock_guard<recursive_mutex> lock(_mutex);
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
const uint64_t block_length = 1;
const unsigned int min_level = 0;
diff --git a/DSLogic-gui/pv/data/snapshot.cpp b/DSLogic-gui/pv/data/snapshot.cpp
index 8cf4b6f..f05452a 100644
--- a/DSLogic-gui/pv/data/snapshot.cpp
+++ b/DSLogic-gui/pv/data/snapshot.cpp
@@ -40,13 +40,13 @@ Snapshot::Snapshot(int unit_size, uint64_t total_sample_count, unsigned int chan
_ring_sample_count(0),
_unit_size(unit_size)
{
- lock_guard<recursive_mutex> lock(_mutex);
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
assert(_unit_size > 0);
}
Snapshot::~Snapshot()
{
- lock_guard<recursive_mutex> lock(_mutex);
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
if (_data != NULL)
free(_data);
_data = NULL;
@@ -73,31 +73,31 @@ bool Snapshot::buf_null() const
uint64_t Snapshot::get_sample_count() const
{
- lock_guard<recursive_mutex> lock(_mutex);
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
return _sample_count / _channel_num;
}
void* Snapshot::get_data() const
{
- lock_guard<recursive_mutex> lock(_mutex);
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
return _data;
}
int Snapshot::get_unit_size() const
{
- lock_guard<recursive_mutex> lock(_mutex);
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
return _unit_size;
}
unsigned int Snapshot::get_channel_num() const
{
- lock_guard<recursive_mutex> lock(_mutex);
+ boost::lock_guard<boost::recursive_mutex> lock(_mutex);
return _channel_num;
}
void Snapshot::append_data(void *data, uint64_t samples)
{
-// lock_guard<recursive_mutex> lock(_mutex);
+// boost::lock_guard<boost::recursive_mutex> lock(_mutex);
// _data = realloc(_data, (_sample_count + samples) * _unit_size +
// sizeof(uint64_t));
if (_sample_count + samples < _total_sample_count)
diff --git a/DSLogic-gui/pv/decoder/ds1wire.cpp b/DSLogic-gui/pv/decoder/ds1wire.cpp
index 1f8d759..04d3ec3 100644
--- a/DSLogic-gui/pv/decoder/ds1wire.cpp
+++ b/DSLogic-gui/pv/decoder/ds1wire.cpp
@@ -53,7 +53,7 @@ const QString ds1Wire::StateTable[TableSize] = {
"DATA"
};
-ds1Wire::ds1Wire(shared_ptr<data::Logic> data, std::list <int > _sel_probes, QMap<QString, QVariant> &_options, QMap<QString, int> _options_index) :
+ds1Wire::ds1Wire(boost::shared_ptr<data::Logic> data, std::list <int > _sel_probes, QMap<QString, QVariant> &_options, QMap<QString, int> _options_index) :
Decoder(data, _sel_probes, _options_index)
{
(void)_options;
@@ -91,12 +91,12 @@ void ds1Wire::decode()
_max_width = 0;
uint8_t cur_state = Unknown;
- const deque< shared_ptr<pv::data::LogicSnapshot> > &snapshots =
+ const deque< boost::shared_ptr<pv::data::LogicSnapshot> > &snapshots =
_data->get_snapshots();
if (snapshots.empty())
return;
- const shared_ptr<pv::data::LogicSnapshot> &snapshot =
+ const boost::shared_ptr<pv::data::LogicSnapshot> &snapshot =
snapshots.front();
uint64_t flag_index1;
@@ -336,11 +336,11 @@ void ds1Wire::get_subsampled_states(std::vector<struct ds_view_state> &states,
{
ds_view_state view_state;
- const deque< shared_ptr<pv::data::LogicSnapshot> > &snapshots =
+ const deque< boost::shared_ptr<pv::data::LogicSnapshot> > &snapshots =
_data->get_snapshots();
if (snapshots.empty())
return;
- const shared_ptr<pv::data::LogicSnapshot> &snapshot =
+ const boost::shared_ptr<pv::data::LogicSnapshot> &snapshot =
snapshots.front();
assert(end <= snapshot->get_sample_count());
diff --git a/DSLogic-gui/pv/decoder/dsdmx512.cpp b/DSLogic-gui/pv/decoder/dsdmx512.cpp
index 19894ec..846f283 100644
--- a/DSLogic-gui/pv/decoder/dsdmx512.cpp
+++ b/DSLogic-gui/pv/decoder/dsdmx512.cpp
@@ -53,7 +53,7 @@ const QString dsDmx512::StateTable[TableSize] = {
"SLOT"
};
-dsDmx512::dsDmx512(shared_ptr<data::Logic> data, std::list <int > _sel_probes, QMap<QString, QVariant> &_options, QMap<QString, int> _options_index) :
+dsDmx512::dsDmx512(boost::shared_ptr<data::Logic> data, std::list <int > _sel_probes, QMap<QString, QVariant> &_options, QMap<QString, int> _options_index) :
Decoder(data, _sel_probes, _options_index)
{
(void)_options;
@@ -91,12 +91,12 @@ void dsDmx512::decode()
_max_width = 0;
uint8_t cur_state = Unknown;
- const deque< shared_ptr<pv::data::LogicSnapshot> > &snapshots =
+ const deque< boost::shared_ptr<pv::data::LogicSnapshot> > &snapshots =
_data->get_snapshots();
if (snapshots.empty())
return;
- const shared_ptr<pv::data::LogicSnapshot> &snapshot =
+ const boost::shared_ptr<pv::data::LogicSnapshot> &snapshot =
snapshots.front();
//uint64_t flag_index;
@@ -261,11 +261,11 @@ void dsDmx512::get_subsampled_states(std::vector<struct ds_view_state> &states,
{
ds_view_state view_state;
- const deque< shared_ptr<pv::data::LogicSnapshot> > &snapshots =
+ const deque< boost::shared_ptr<pv::data::LogicSnapshot> > &snapshots =
_data->get_snapshots();
if (snapshots.empty())
return;
- const shared_ptr<pv::data::LogicSnapshot> &snapshot =
+ const boost::shared_ptr<pv::data::LogicSnapshot> &snapshot =
snapshots.front();
assert(end <= snapshot->get_sample_count());
diff --git a/DSLogic-gui/pv/decoder/dsi2c.cpp b/DSLogic-gui/pv/decoder/dsi2c.cpp
index 9f61b86..b2bc440 100644
--- a/DSLogic-gui/pv/decoder/dsi2c.cpp
+++ b/DSLogic-gui/pv/decoder/dsi2c.cpp
@@ -52,7 +52,7 @@ const QString dsI2c::StateTable[TableSize] = {
"DATA"
};
-dsI2c::dsI2c(shared_ptr<data::Logic> data, std::list <int > _sel_probes, QMap<QString, QVariant> &_options, QMap<QString, int> _options_index) :
+dsI2c::dsI2c(boost::shared_ptr<data::Logic> data, std::list <int > _sel_probes, QMap<QString, QVariant> &_options, QMap<QString, int> _options_index) :
Decoder(data, _sel_probes, _options_index)
{
(void)_options;
@@ -91,12 +91,12 @@ void dsI2c::decode()
_max_width = 0;
uint8_t cur_state = Unknown;
- const deque< shared_ptr<pv::data::LogicSnapshot> > &snapshots =
+ const deque< boost::shared_ptr<pv::data::LogicSnapshot> > &snapshots =
_data->get_snapshots();
if (snapshots.empty())
return;
- const shared_ptr<pv::data::LogicSnapshot> &snapshot =
+ const boost::shared_ptr<pv::data::LogicSnapshot> &snapshot =
snapshots.front();
uint64_t flag_index;
@@ -185,7 +185,7 @@ void dsI2c::cmd_decode(const boost::shared_ptr<data::LogicSnapshot> &snapshot)
}
}
-void dsI2c::data_decode(const shared_ptr<data::LogicSnapshot> &snapshot)
+void dsI2c::data_decode(const boost::shared_ptr<data::LogicSnapshot> &snapshot)
{
uint8_t cur_state;
const uint8_t *src_ptr;
@@ -246,11 +246,11 @@ void dsI2c::get_subsampled_states(std::vector<struct ds_view_state> &states,
{
ds_view_state view_state;
- const deque< shared_ptr<pv::data::LogicSnapshot> > &snapshots =
+ const deque< boost::shared_ptr<pv::data::LogicSnapshot> > &snapshots =
_data->get_snapshots();
if (snapshots.empty())
return;
- const shared_ptr<pv::data::LogicSnapshot> &snapshot =
+ const boost::shared_ptr<pv::data::LogicSnapshot> &snapshot =
snapshots.front();
assert(end <= snapshot->get_sample_count());
diff --git a/DSLogic-gui/pv/decoder/dsserial.cpp b/DSLogic-gui/pv/decoder/dsserial.cpp
index 5b23186..aee9a4c 100644
--- a/DSLogic-gui/pv/decoder/dsserial.cpp
+++ b/DSLogic-gui/pv/decoder/dsserial.cpp
@@ -53,7 +53,7 @@ const QString dsSerial::StateTable[TableSize] = {
"DATA"
};
-dsSerial::dsSerial(shared_ptr<data::Logic> data, std::list <int > _sel_probes, QMap<QString, QVariant> &_options, QMap<QString, int> _options_index) :
+dsSerial::dsSerial(boost::shared_ptr<data::Logic> data, std::list <int > _sel_probes, QMap<QString, QVariant> &_options, QMap<QString, int> _options_index) :
Decoder(data, _sel_probes, _options_index)
{
assert(_sel_probes.size() == 1);
@@ -102,12 +102,12 @@ void dsSerial::decode()
assert(_data);
uint8_t cur_state = Unknown;
- const deque< shared_ptr<pv::data::LogicSnapshot> > &snapshots =
+ const deque< boost::shared_ptr<pv::data::LogicSnapshot> > &snapshots =
_data->get_snapshots();
if (snapshots.empty())
return;
- const shared_ptr<pv::data::LogicSnapshot> &snapshot =
+ const boost::shared_ptr<pv::data::LogicSnapshot> &snapshot =
snapshots.front();
uint64_t flag_index;
@@ -117,7 +117,7 @@ void dsSerial::decode()
uint64_t left = 0;
uint64_t right = snapshot->get_sample_count() - 1;
float samplesPerBit;
- int sampleOffset;
+ //int sampleOffset;
int i;
_max_width = 0;
_min_width = right;
@@ -127,7 +127,7 @@ void dsSerial::decode()
samplesPerBit = _data->get_samplerate() * 1.0f / _baudrate;
else
samplesPerBit = snapshot->get_min_pulse(left, right, _serial_index);
- sampleOffset = samplesPerBit / 2;
+ //sampleOffset = samplesPerBit / 2;
if (!_state_index.empty())
_state_index.clear();
@@ -174,7 +174,7 @@ void dsSerial::decode()
}
-void dsSerial::data_decode(const shared_ptr<data::LogicSnapshot> &snapshot, uint64_t start, uint64_t stop, float samplesPerBit)
+void dsSerial::data_decode(const boost::shared_ptr<data::LogicSnapshot> &snapshot, uint64_t start, uint64_t stop, float samplesPerBit)
{
(void)stop;
@@ -238,11 +238,11 @@ void dsSerial::get_subsampled_states(std::vector<struct ds_view_state> &states,
{
ds_view_state view_state;
- const deque< shared_ptr<pv::data::LogicSnapshot> > &snapshots =
+ const deque< boost::shared_ptr<pv::data::LogicSnapshot> > &snapshots =
_data->get_snapshots();
if (snapshots.empty())
return;
- const shared_ptr<pv::data::LogicSnapshot> &snapshot =
+ const boost::shared_ptr<pv::data::LogicSnapshot> &snapshot =
snapshots.front();
assert(end <= snapshot->get_sample_count());
diff --git a/DSLogic-gui/pv/decoder/dsspi.cpp b/DSLogic-gui/pv/decoder/dsspi.cpp
index 88ff8db..3b95507 100644
--- a/DSLogic-gui/pv/decoder/dsspi.cpp
+++ b/DSLogic-gui/pv/decoder/dsspi.cpp
@@ -45,7 +45,7 @@ const QString dsSpi::StateTable[TableSize] = {
"DATA"
};
-dsSpi::dsSpi(shared_ptr<data::Logic> data, std::list <int > _sel_probes, QMap<QString, QVariant> &_options, QMap<QString, int> _options_index) :
+dsSpi::dsSpi(boost::shared_ptr<data::Logic> data, std::list <int > _sel_probes, QMap<QString, QVariant> &_options, QMap<QString, int> _options_index) :
Decoder(data, _sel_probes, _options_index)
{
_cpol = _options.value("cpol").toBool();
@@ -125,12 +125,12 @@ void dsSpi::decode()
_max_width = 0;
uint8_t cur_state = Unknown;
- const deque< shared_ptr<pv::data::LogicSnapshot> > &snapshots =
+ const deque< boost::shared_ptr<pv::data::LogicSnapshot> > &snapshots =
_data->get_snapshots();
if (snapshots.empty())
return;
- const shared_ptr<pv::data::LogicSnapshot> &snapshot =
+ const boost::shared_ptr<pv::data::LogicSnapshot> &snapshot =
snapshots.front();
const uint64_t ssn_mask = 1ULL << _ssn_index;
@@ -191,7 +191,7 @@ void dsSpi::decode()
}
}
-void dsSpi::data_decode(const shared_ptr<data::LogicSnapshot> &snapshot)
+void dsSpi::data_decode(const boost::shared_ptr<data::LogicSnapshot> &snapshot)
{
uint8_t cur_state;
const uint8_t *src_ptr;
@@ -256,11 +256,11 @@ void dsSpi::get_subsampled_states(std::vector<struct ds_view_state> &states,
{
ds_view_state view_state;
- const deque< shared_ptr<pv::data::LogicSnapshot> > &snapshots =
+ const deque< boost::shared_ptr<pv::data::LogicSnapshot> > &snapshots =
_data->get_snapshots();
if (snapshots.empty())
return;
- const shared_ptr<pv::data::LogicSnapshot> &snapshot =
+ const boost::shared_ptr<pv::data::LogicSnapshot> &snapshot =
snapshots.front();
assert(end <= snapshot->get_sample_count());
diff --git a/DSLogic-gui/pv/devicemanager.cpp b/DSLogic-gui/pv/devicemanager.cpp
index 4a17ca9..66e3500 100644
--- a/DSLogic-gui/pv/devicemanager.cpp
+++ b/DSLogic-gui/pv/devicemanager.cpp
@@ -29,12 +29,15 @@
#include <stdexcept>
#include <string>
+#include <QtGui/QApplication>
#include <QObject>
#include <QDebug>
+#include <QDir>
#include <libsigrok4DSLogic/libsigrok.h>
using namespace std;
+char config_path[256];
namespace pv {
@@ -98,6 +101,15 @@ list<sr_dev_inst*> DeviceManager::driver_scan(
// Release this driver and all it's attached devices
release_driver(driver);
+ // Check If DSLogic driver
+ if (strcmp(driver->name, "DSLogic") == 0) {
+ QDir dir(QApplication::applicationDirPath());
+ if (!dir.cd("res"))
+ return driver_devices;
+ std::string str = dir.absolutePath().toStdString() + "/";
+ strcpy(config_path, str.c_str());
+ }
+
// Do the scan
GSList *const devices = sr_driver_scan(driver, drvopts);
for (GSList *l = devices; l; l = l->next)
diff --git a/DSLogic-gui/pv/dialogs/deviceoptions.cpp b/DSLogic-gui/pv/dialogs/deviceoptions.cpp
index 75023c3..726fc92 100644
--- a/DSLogic-gui/pv/dialogs/deviceoptions.cpp
+++ b/DSLogic-gui/pv/dialogs/deviceoptions.cpp
@@ -50,7 +50,9 @@ DeviceOptions::DeviceOptions(QWidget *parent, struct sr_dev_inst *sdi) :
setWindowTitle(tr("Configure Device"));
setLayout(&_layout);
+ _last_mode = sdi->mode;
_mode_comboBox.addItem(mode_strings[LOGIC]);
+ _mode_comboBox.addItem(mode_strings[DSO]);
_mode_comboBox.addItem(mode_strings[ANALOG]);
_mode_comboBox.setCurrentIndex(_sdi->mode);
_props_box.setLayout(&_props_box_layout);
@@ -77,10 +79,11 @@ void DeviceOptions::accept()
QDialog::accept();
+ _last_mode = _sdi->mode;
// Commit the properties
- const vector< shared_ptr<pv::prop::Property> > &properties =
+ const vector< boost::shared_ptr<pv::prop::Property> > &properties =
_device_options_binding.properties();
- BOOST_FOREACH(shared_ptr<pv::prop::Property> p, properties) {
+ BOOST_FOREACH(boost::shared_ptr<pv::prop::Property> p, properties) {
assert(p);
p->commit();
}
@@ -96,6 +99,15 @@ void DeviceOptions::accept()
}
}
+void DeviceOptions::reject()
+{
+ using namespace Qt;
+ QDialog::reject();
+
+ // Mode Recovery
+ sr_config_set(_sdi, SR_CONF_DEVICE_MODE, g_variant_new_string(_mode_comboBox.itemText(_last_mode).toLocal8Bit()));
+}
+
QWidget* DeviceOptions::get_property_form()
{
QWidget *const form = new QWidget(this);
@@ -103,9 +115,9 @@ QWidget* DeviceOptions::get_property_form()
form->setLayout(layout);
layout->addRow("Device Mode", &_mode_comboBox);
- const vector< shared_ptr<pv::prop::Property> > &properties =
+ const vector< boost::shared_ptr<pv::prop::Property> > &properties =
_device_options_binding.properties();
- BOOST_FOREACH(shared_ptr<pv::prop::Property> p, properties)
+ BOOST_FOREACH(boost::shared_ptr<pv::prop::Property> p, properties)
{
assert(p);
const QString label = p->labeled_widget() ? QString() : p->name();
@@ -182,7 +194,9 @@ void DeviceOptions::disable_all_probes()
void DeviceOptions::mode_changed(QString mode)
{
- sr_config_set(_sdi, SR_CONF_DEVICE_MODE, g_variant_new_string(mode.toLocal8Bit()));
+ (void)mode;
+ // Commit mode
+ sr_config_set(_sdi, SR_CONF_DEVICE_MODE, g_variant_new_string(_mode_comboBox.currentText().toLocal8Bit()));
setup_probes();
}
diff --git a/DSLogic-gui/pv/dialogs/deviceoptions.h b/DSLogic-gui/pv/dialogs/deviceoptions.h
index 2ee2534..ad804d2 100644
--- a/DSLogic-gui/pv/dialogs/deviceoptions.h
+++ b/DSLogic-gui/pv/dialogs/deviceoptions.h
@@ -51,6 +51,7 @@ public:
protected:
void accept();
+ void reject();
private:
@@ -67,6 +68,7 @@ private slots:
private:
struct sr_dev_inst *const _sdi;
+ int _last_mode;
QVBoxLayout _layout;
diff --git a/DSLogic-gui/pv/dialogs/search.cpp b/DSLogic-gui/pv/dialogs/search.cpp
index 50c15c9..5945491 100644
--- a/DSLogic-gui/pv/dialogs/search.cpp
+++ b/DSLogic-gui/pv/dialogs/search.cpp
@@ -22,33 +22,55 @@
#include "search.h"
-#include "ui_search.h"
#include <assert.h>
+#include <QRegExpValidator>
namespace pv {
namespace dialogs {
Search::Search(QWidget *parent, struct sr_dev_inst *sdi, QString pattern) :
QDialog(parent),
- ui(new Ui::Search),
_sdi(sdi)
{
assert(_sdi);
- ui->setupUi(this);
+
+ QFont font("Monaco");
+ font.setStyleHint(QFont::Monospace);
+ font.setFixedPitch(true);
QRegExp value_rx("[10XRFCxrfc ]+");
QValidator *value_validator = new QRegExpValidator(value_rx, this);
- //ui->_value_lineEdit->setText("X X X X X X X X X X X X X X X X");
- ui->_value_lineEdit->setText(pattern);
- ui->_value_lineEdit->setValidator(value_validator);
- ui->_value_lineEdit->setMaxLength(16 * 2 - 1);
- ui->_value_lineEdit->setInputMask("X X X X X X X X X X X X X X X X");
+
+ search_lineEdit.setText(pattern);
+ search_lineEdit.setValidator(value_validator);
+ search_lineEdit.setMaxLength(16 * 2 - 1);
+ search_lineEdit.setInputMask("X X X X X X X X X X X X X X X X");
+ search_lineEdit.setFont(font);
+
+ QLabel *search_label = new QLabel("1 1 1 1 1\n5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0");
+ search_label->setFont(font);
+
+ search_buttonBox.addButton(QDialogButtonBox::Ok);
+ search_buttonBox.addButton(QDialogButtonBox::Cancel);
+
+ QGridLayout *search_layout = new QGridLayout();
+ search_layout->addWidget(search_label, 0, 1);
+ search_layout->addWidget(new QLabel("Search Value: "), 1,0, Qt::AlignRight);
+ search_layout->addWidget(&search_lineEdit, 1, 1);
+ search_layout->addWidget(new QLabel(" "), 2,0);
+ search_layout->addWidget(new QLabel("X: Don't care\n0: Low level\n1: High level\nR: Rising edge\nF: Falling edge\nC: Rising/Falling edge"), 3, 0);
+ search_layout->addWidget(&search_buttonBox, 4, 2);
+ //search_layout->addStretch(1);
+
+ setLayout(search_layout);
+
+ connect(&search_buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
+ connect(&search_buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
}
Search::~Search()
{
- delete ui;
}
void Search::accept()
@@ -60,7 +82,7 @@ void Search::accept()
QString Search::get_pattern()
{
- QString pattern = ui->_value_lineEdit->text();
+ QString pattern = search_lineEdit.text();
//pattern.remove(QChar('/r'), Qt::CaseInsensitive);
return pattern;
}
diff --git a/DSLogic-gui/pv/dialogs/search.h b/DSLogic-gui/pv/dialogs/search.h
index a4dea4c..07c3312 100644
--- a/DSLogic-gui/pv/dialogs/search.h
+++ b/DSLogic-gui/pv/dialogs/search.h
@@ -27,13 +27,12 @@
#include <QDialog>
#include <QLabel>
#include <QLineEdit>
+#include <QVBoxLayout>
+#include <QGridLayout>
+#include <QDialogButtonBox>
#include "../sigsession.h"
#include <libsigrok4DSLogic/libsigrok.h>
-namespace Ui {
-class Search;
-}
-
namespace pv {
namespace dialogs {
@@ -56,7 +55,8 @@ signals:
public slots:
private:
- Ui::Search *ui;
+ QLineEdit search_lineEdit;
+ QDialogButtonBox search_buttonBox;
sr_dev_inst *_sdi;
};
diff --git a/DSLogic-gui/pv/dock/dsotriggerdock.cpp b/DSLogic-gui/pv/dock/dsotriggerdock.cpp
new file mode 100644
index 0000000..d8f8277
--- /dev/null
+++ b/DSLogic-gui/pv/dock/dsotriggerdock.cpp
@@ -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
diff --git a/DSLogic-gui/pv/dock/dsotriggerdock.h b/DSLogic-gui/pv/dock/dsotriggerdock.h
new file mode 100644
index 0000000..5c135c4
--- /dev/null
+++ b/DSLogic-gui/pv/dock/dsotriggerdock.h
@@ -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
diff --git a/DSLogic-gui/pv/dock/measuredock.cpp b/DSLogic-gui/pv/dock/measuredock.cpp
index e2ab59d..43c43cf 100644
--- a/DSLogic-gui/pv/dock/measuredock.cpp
+++ b/DSLogic-gui/pv/dock/measuredock.cpp
@@ -32,6 +32,8 @@
#include <QPainter>
#include <QRegExpValidator>
+#include "libsigrok4DSLogic/libsigrok.h"
+
namespace pv {
namespace dock {
diff --git a/DSLogic-gui/pv/dock/triggerdock.cpp b/DSLogic-gui/pv/dock/triggerdock.cpp
index 38e89b8..d5fc890 100644
--- a/DSLogic-gui/pv/dock/triggerdock.cpp
+++ b/DSLogic-gui/pv/dock/triggerdock.cpp
@@ -31,6 +31,8 @@
#include <QRegExpValidator>
#include <QMessageBox>
+#include "libsigrok4DSLogic/libsigrok.h"
+
namespace pv {
namespace dock {
@@ -40,6 +42,10 @@ TriggerDock::TriggerDock(QWidget *parent, SigSession &session) :
{
int i;
+ QFont font("Monaco");
+ font.setStyleHint(QFont::Monospace);
+ font.setFixedPitch(true);
+
simple_radioButton = new QRadioButton("Simple Trigger", this);
simple_radioButton->setChecked(true);
adv_radioButton = new QRadioButton("Advanced Trigger", this);
@@ -75,6 +81,7 @@ TriggerDock::TriggerDock(QWidget *parent, SigSession &session) :
_logic_comboBox_list.push_back(_logic_comboBox);
QLineEdit *_value0_lineEdit = new QLineEdit("X X X X X X X X X X X X X X X X", this);
+ _value0_lineEdit->setFont(font);
_value0_lineEdit->setValidator(value_validator);
_value0_lineEdit->setMaxLength(TriggerProbes * 2 - 1);
_value0_lineEdit->setInputMask("X X X X X X X X X X X X X X X X");
@@ -89,6 +96,7 @@ TriggerDock::TriggerDock(QWidget *parent, SigSession &session) :
_inv0_comboBox_list.push_back(_inv0_comboBox);
QLineEdit *_value1_lineEdit = new QLineEdit("X X X X X X X X X X X X X X X X", this);
+ _value1_lineEdit->setFont(font);
_value1_lineEdit->setValidator(value_validator);
_value1_lineEdit->setMaxLength(TriggerProbes * 2 - 1);
_value1_lineEdit->setInputMask("X X X X X X X X X X X X X X X X");
@@ -102,15 +110,14 @@ TriggerDock::TriggerDock(QWidget *parent, SigSession &session) :
_inv1_comboBox->addItem(tr("!="));
_inv1_comboBox_list.push_back(_inv1_comboBox);
- QLabel *value_exp0_label = new QLabel("1 1 1 1 1 1", this);
- QLabel *value_exp1_label = new QLabel("5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0", this);
+ QLabel *value_exp_label = new QLabel("1 1 1 1 1 1\n5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0", this);
QLabel *inv_exp_label = new QLabel("Inv", this);
QLabel *count_exp_label = new QLabel("Counter", this);
+ value_exp_label->setFont(font);
QVBoxLayout *stage_layout = new QVBoxLayout();
QGridLayout *stage_glayout = new QGridLayout();
- stage_glayout->addWidget(value_exp0_label, 0, 0);
- stage_glayout->addWidget(value_exp1_label, 1, 0);
+ stage_glayout->addWidget(value_exp_label, 1, 0);
stage_glayout->addWidget(inv_exp_label, 1, 1);
stage_glayout->addWidget(count_exp_label, 1, 2);
stage_glayout->addWidget(_value0_lineEdit, 2, 0);
@@ -121,13 +128,8 @@ TriggerDock::TriggerDock(QWidget *parent, SigSession &session) :
stage_glayout->addWidget(_inv1_comboBox, 3, 1);
stage_glayout->addWidget(_count1_spinBox, 3, 2);
stage_layout->addLayout(stage_glayout);
- stage_layout->addSpacing(124);
- stage_layout->addWidget(new QLabel("X: Don't care"));
- stage_layout->addWidget(new QLabel("0: Low level"));
- stage_layout->addWidget(new QLabel("1: High level"));
- stage_layout->addWidget(new QLabel("R: Rising edge"));
- stage_layout->addWidget(new QLabel("F: Falling edge"));
- stage_layout->addWidget(new QLabel("C: Rising/Falling edge"));
+ stage_layout->addSpacing(160);
+ stage_layout->addWidget(new QLabel("X: Don't care\n0: Low level\n1: High level\nR: Rising edge\nF: Falling edge\nC: Rising/Falling edge"));
stage_layout->addStretch(1);
QGroupBox *_stage_groupBox = new QGroupBox("Stage"+QString::number(i), this);
diff --git a/DSLogic-gui/pv/mainwindow.cpp b/DSLogic-gui/pv/mainwindow.cpp
index 32c7a94..9a7bb84 100644
--- a/DSLogic-gui/pv/mainwindow.cpp
+++ b/DSLogic-gui/pv/mainwindow.cpp
@@ -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);
@@ -242,15 +251,17 @@ void MainWindow::setup_ui()
// Populate the device list and select the initially selected device
update_device_list();
-// connect(_device_bar, SIGNAL(device_selected()), this,
-// SLOT(device_selected()));
connect(_device_bar, SIGNAL(device_selected()), this,
- SLOT(init()));
+ SLOT(device_selected()));
+// connect(_device_bar, SIGNAL(device_selected()), this,
+// SLOT(init()));
connect(_device_bar, SIGNAL(device_updated()), this,
SLOT(update()));
- connect(_sampling_bar, SIGNAL(run_stop()), this,
- SLOT(run_stop()));
- addToolBar(_sampling_bar);
+ connect(_sampling_bar, SIGNAL(device_reload()), this,
+ SLOT(init()));
+ connect(_sampling_bar, SIGNAL(run_stop()), this,
+ SLOT(run_stop()));
+ addToolBar(_sampling_bar);
addToolBar(_trig_bar);
addToolBar(_device_bar);
addToolBar(_file_bar);
@@ -294,11 +305,12 @@ 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);
// Set the title
- setWindowTitle(QApplication::translate("MainWindow", "DSLogic", 0,
+ setWindowTitle(QApplication::translate("MainWindow", "DSLogic(Beta)", 0,
QApplication::UnicodeUTF8));
// Setup _session events
@@ -310,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()));
@@ -325,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()
@@ -372,10 +394,12 @@ void MainWindow::update_device_list(struct sr_dev_inst *selected_device)
}
}
- #ifdef HAVE_LA_DSLOGIC
- _session.start_hot_plug_proc(boost::bind(&MainWindow::session_error, this,
+// #ifdef HAVE_LA_DSLOGIC
+ _session.start_hotplug_proc(boost::bind(&MainWindow::session_error, this,
QString("Hotplug failed"), _1));
- #endif
+ _session.start_dso_ctrl_proc(boost::bind(&MainWindow::session_error, this,
+ QString("Hotplug failed"), _1));
+// #endif
}
void MainWindow::device_change()
@@ -408,11 +432,11 @@ void MainWindow::device_change()
device_detach();
}
- #ifdef HAVE_LA_DSLOGIC
- _session.stop_hot_plug_proc();
- _session.start_hot_plug_proc(boost::bind(&MainWindow::session_error, this,
+// #ifdef HAVE_LA_DSLOGIC
+ _session.stop_hotplug_proc();
+ _session.start_hotplug_proc(boost::bind(&MainWindow::session_error, this,
QString("Hotplug failed"), _1));
- #endif
+// #endif
}
@@ -444,16 +468,44 @@ 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()
{
- _session.stop_hot_plug_proc();
+ _session.stop_hotplug_proc();
if (_session.get_capture_state() == SigSession::Running)
_session.stop_capture();
@@ -470,7 +522,7 @@ void MainWindow::device_attach()
void MainWindow::device_detach()
{
- _session.stop_hot_plug_proc();
+ _session.stop_hotplug_proc();
if (_session.get_capture_state() == SigSession::Running)
_session.stop_capture();
@@ -506,8 +558,34 @@ 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();
QMessageBox msg(this);
msg.setText("Data Error");
msg.setInformativeText("the receive data are not consist with pre-defined test data");
@@ -518,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);
}
@@ -534,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)
diff --git a/DSLogic-gui/pv/mainwindow.h b/DSLogic-gui/pv/mainwindow.h
index b89aee9..9be748a 100644
--- a/DSLogic-gui/pv/mainwindow.h
+++ b/DSLogic-gui/pv/mainwindow.h
@@ -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;
diff --git a/DSLogic-gui/pv/prop/binding/binding_deviceoptions.cpp b/DSLogic-gui/pv/prop/binding/binding_deviceoptions.cpp
index 189afcc..05b488e 100644
--- a/DSLogic-gui/pv/prop/binding/binding_deviceoptions.cpp
+++ b/DSLogic-gui/pv/prop/binding/binding_deviceoptions.cpp
@@ -83,7 +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;
@@ -99,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)
@@ -131,13 +139,13 @@ void DeviceOptions::config_setter(
void DeviceOptions::bind_bool(const QString &name, int key)
{
- _properties.push_back(shared_ptr<Property>(
+ _properties.push_back(boost::shared_ptr<Property>(
new Bool(name, bind(config_getter, _sdi, key),
bind(config_setter, _sdi, key, _1))));
}
void DeviceOptions::bind_enum(const QString &name, int key,
- GVariant *const gvar_list, function<QString (GVariant*)> printer)
+ GVariant *const gvar_list, boost::function<QString (GVariant*)> printer)
{
GVariant *gvar;
GVariantIter iter;
@@ -149,7 +157,7 @@ void DeviceOptions::bind_enum(const QString &name, int key,
while ((gvar = g_variant_iter_next_value (&iter)))
values.push_back(make_pair(gvar, printer(gvar)));
- _properties.push_back(shared_ptr<Property>(
+ _properties.push_back(boost::shared_ptr<Property>(
new Enum(name, values,
bind(config_getter, _sdi, key),
bind(config_setter, _sdi, key, _1))));
@@ -158,7 +166,7 @@ void DeviceOptions::bind_enum(const QString &name, int key,
void DeviceOptions::bind_int(const QString &name, int key, QString suffix,
optional< std::pair<int64_t, int64_t> > range)
{
- _properties.push_back(shared_ptr<Property>(
+ _properties.push_back(boost::shared_ptr<Property>(
new Int(name, suffix, range,
bind(config_getter, _sdi, key),
bind(config_setter, _sdi, key, _1))));
@@ -197,7 +205,7 @@ void DeviceOptions::bind_samplerate(const QString &name,
assert(num_elements == 3);
- _properties.push_back(shared_ptr<Property>(
+ _properties.push_back(boost::shared_ptr<Property>(
new Double(name, 0, QObject::tr("Hz"),
make_pair((double)elements[0], (double)elements[1]),
(double)elements[2],
diff --git a/DSLogic-gui/pv/sigsession.cpp b/DSLogic-gui/pv/sigsession.cpp
index 684f346..27d7946 100644
--- a/DSLogic-gui/pv/sigsession.cpp
+++ b/DSLogic-gui/pv/sigsession.cpp
@@ -26,11 +26,14 @@
#include "devicemanager.h"
#include "data/analog.h"
#include "data/analogsnapshot.h"
+#include "data/dso.h"
+#include "data/dsosnapshot.h"
#include "data/logic.h"
#include "data/logicsnapshot.h"
#include "data/group.h"
#include "data/groupsnapshot.h"
#include "view/analogsignal.h"
+#include "view/dsosignal.h"
#include "view/logicsignal.h"
#include "view/groupsignal.h"
#include "view/protocolsignal.h"
@@ -59,8 +62,7 @@ SigSession::SigSession(DeviceManager &device_manager) :
_sdi(NULL),
_capture_state(Init),
_last_sample_rate(1),
- _total_sample_len(1),
- _hot_plug_handle(NULL)
+ _total_sample_len(1)
{
// TODO: This should not be necessary
_session = this;
@@ -71,20 +73,28 @@ SigSession::SigSession(DeviceManager &device_manager) :
_protocol_cnt = 0;
_decoderFactory = new decoder::DecoderFactory();
ds_trigger_init();
+
+ _vDial_changed = false;
+ _hDial_changed = false;
+ _dso_ctrl_channel = 0;
+ register_hotplug_callback();
}
SigSession::~SigSession()
{
- stop_capture();
+ stop_capture();
- if (_sampling_thread.get())
- _sampling_thread->join();
- _sampling_thread.reset();
+ if (_sampling_thread.get())
+ _sampling_thread->join();
+ _sampling_thread.reset();
- if (_hot_plug_handle)
- stop_hot_plug_proc();
+ if (_hotplug_handle) {
+ stop_hotplug_proc();
+ deregister_hotplug_callback();
+ }
ds_trigger_destroy();
+ stop_dso_ctrl_proc();
// TODO: This should not be necessary
_session = NULL;
@@ -114,15 +124,18 @@ int SigSession::set_device(struct sr_dev_inst *sdi)
{
int ret = SR_ERR;
- if (sdi)
+ if (_sdi == NULL) {
ret = _device_manager.use_device(sdi, this);
- if (ret == SR_OK && (sdi != _sdi) && _sdi) {
- _device_manager.release_device(_sdi);
- }
- if (ret == SR_OK)
_sdi = sdi;
-
- set_capture_state(Init);
+ set_capture_state(Init);
+ } else if (sdi != _sdi) {
+ ret = _device_manager.use_device(sdi, this);
+ _device_manager.release_device(_sdi);
+ _sdi = sdi;
+ set_capture_state(Init);
+ } else {
+ ret = SR_OK;
+ }
return ret;
}
@@ -137,12 +150,25 @@ void SigSession::release_device(struct sr_dev_inst *sdi)
void SigSession::save_file(const std::string &name){
if (_sdi->mode == LOGIC) {
- const deque< shared_ptr<pv::data::LogicSnapshot> > &snapshots =
+ const deque< boost::shared_ptr<pv::data::LogicSnapshot> > &snapshots =
_logic_data->get_snapshots();
if (snapshots.empty())
return;
- const shared_ptr<pv::data::LogicSnapshot> &snapshot =
+ const boost::shared_ptr<pv::data::LogicSnapshot> &snapshot =
+ snapshots.front();
+
+ sr_session_save(name.c_str(), _sdi,
+ (unsigned char*)snapshot->get_data(),
+ snapshot->get_unit_size(),
+ snapshot->get_sample_count());
+ } else if (_sdi->mode == DSO){
+ const deque< boost::shared_ptr<pv::data::DsoSnapshot> > &snapshots =
+ _dso_data->get_snapshots();
+ if (snapshots.empty())
+ return;
+
+ const boost::shared_ptr<pv::data::DsoSnapshot> &snapshot =
snapshots.front();
sr_session_save(name.c_str(), _sdi,
@@ -150,12 +176,12 @@ void SigSession::save_file(const std::string &name){
snapshot->get_unit_size(),
snapshot->get_sample_count());
} else {
- const deque< shared_ptr<pv::data::AnalogSnapshot> > &snapshots =
+ const deque< boost::shared_ptr<pv::data::AnalogSnapshot> > &snapshots =
_analog_data->get_snapshots();
if (snapshots.empty())
return;
- const shared_ptr<pv::data::AnalogSnapshot> &snapshot =
+ const boost::shared_ptr<pv::data::AnalogSnapshot> &snapshot =
snapshots.front();
sr_session_save(name.c_str(), _sdi,
@@ -166,7 +192,7 @@ void SigSession::save_file(const std::string &name){
}
void SigSession::load_file(const string &name,
- function<void (const QString)> error_handler)
+ boost::function<void (const QString)> error_handler)
{
stop_capture();
_sampling_thread.reset(new boost::thread(
@@ -176,12 +202,12 @@ void SigSession::load_file(const string &name,
SigSession::capture_state SigSession::get_capture_state() const
{
- lock_guard<mutex> lock(_sampling_mutex);
+ boost::lock_guard<boost::mutex> lock(_sampling_mutex);
return _capture_state;
}
void SigSession::start_capture(uint64_t record_length,
- function<void (const QString)> error_handler)
+ boost::function<void (const QString)> error_handler)
{
stop_capture();
@@ -199,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,
@@ -215,7 +257,6 @@ void SigSession::stop_capture()
{
if (get_capture_state() == Stopped)
return;
-
sr_session_stop();
// Check that sampling stopped
@@ -224,15 +265,15 @@ void SigSession::stop_capture()
_sampling_thread.reset();
}
-vector< shared_ptr<view::Signal> > SigSession::get_signals()
+vector< boost::shared_ptr<view::Signal> > SigSession::get_signals()
{
- lock_guard<mutex> lock(_signals_mutex);
+ boost::lock_guard<boost::mutex> lock(_signals_mutex);
return _signals;
}
-vector< shared_ptr<view::Signal> > SigSession::get_pro_signals()
+vector< boost::shared_ptr<view::Signal> > SigSession::get_pro_signals()
{
- lock_guard<mutex> lock(_signals_mutex);
+ boost::lock_guard<boost::mutex> lock(_signals_mutex);
return _protocol_signals;
}
@@ -255,6 +296,24 @@ int SigSession::get_logic_probe_cnt(const sr_dev_inst *sdi)
return logic_probe_cnt;
}
+int SigSession::get_dso_probe_cnt(const sr_dev_inst *sdi)
+{
+ unsigned int dso_probe_cnt = 0;
+ for (const GSList *l = sdi->probes; l; l = l->next) {
+ const sr_probe *const probe = (const sr_probe *)l->data;
+ if (!probe->enabled)
+ continue;
+
+ switch(probe->type) {
+ case SR_PROBE_DSO:
+ dso_probe_cnt++;
+ break;
+ }
+ }
+
+ return dso_probe_cnt;
+}
+
int SigSession::get_analog_probe_cnt(const sr_dev_inst *sdi)
{
unsigned int analog_probe_cnt = 0;
@@ -281,24 +340,36 @@ boost::shared_ptr<data::Logic> SigSession::get_data()
void* SigSession::get_buf(int& unit_size, uint64_t &length)
{
if (_sdi->mode == LOGIC) {
- const deque< shared_ptr<pv::data::LogicSnapshot> > &snapshots =
+ const deque< boost::shared_ptr<pv::data::LogicSnapshot> > &snapshots =
_logic_data->get_snapshots();
if (snapshots.empty())
return NULL;
- const shared_ptr<pv::data::LogicSnapshot> &snapshot =
+ const boost::shared_ptr<pv::data::LogicSnapshot> &snapshot =
+ snapshots.front();
+
+ unit_size = snapshot->get_unit_size();
+ length = snapshot->get_sample_count();
+ return snapshot->get_data();
+ } else if (_sdi->mode == DSO) {
+ const deque< boost::shared_ptr<pv::data::DsoSnapshot> > &snapshots =
+ _dso_data->get_snapshots();
+ if (snapshots.empty())
+ return NULL;
+
+ const boost::shared_ptr<pv::data::DsoSnapshot> &snapshot =
snapshots.front();
unit_size = snapshot->get_unit_size();
length = snapshot->get_sample_count();
return snapshot->get_data();
} else {
- const deque< shared_ptr<pv::data::AnalogSnapshot> > &snapshots =
+ const deque< boost::shared_ptr<pv::data::AnalogSnapshot> > &snapshots =
_analog_data->get_snapshots();
if (snapshots.empty())
return NULL;
- const shared_ptr<pv::data::AnalogSnapshot> &snapshot =
+ const boost::shared_ptr<pv::data::AnalogSnapshot> &snapshot =
snapshots.front();
unit_size = snapshot->get_unit_size();
@@ -309,14 +380,14 @@ void* SigSession::get_buf(int& unit_size, uint64_t &length)
void SigSession::set_capture_state(capture_state state)
{
- lock_guard<mutex> lock(_sampling_mutex);
+ boost::lock_guard<boost::mutex> lock(_sampling_mutex);
_capture_state = state;
data_updated();
capture_state_changed(state);
}
void SigSession::load_thread_proc(const string name,
- function<void (const QString)> error_handler)
+ boost::function<void (const QString)> error_handler)
{
if (sr_session_load(name.c_str()) != SR_OK) {
error_handler(tr("Failed to load file."));
@@ -339,79 +410,79 @@ void SigSession::load_thread_proc(const string name,
// Confirm that SR_DF_END was received
assert(!_cur_logic_snapshot);
+ assert(!_cur_dso_snapshot);
assert(!_cur_analog_snapshot);
}
void SigSession::sample_thread_proc(struct sr_dev_inst *sdi,
uint64_t record_length,
- function<void (const QString)> error_handler)
+ boost::function<void (const QString)> error_handler)
{
-// while(1) {
- assert(sdi);
- assert(error_handler);
-
- if (!_adv_trigger) {
- /* simple trigger check trigger_enable */
- ds_trigger_set_en(false);
- BOOST_FOREACH(const shared_ptr<view::Signal> s, _signals)
- {
- assert(s);
- if (s->get_trig() != 0) {
- ds_trigger_set_en(true);
- s->set_trig(s->get_trig());
- }
- }
- } else {
- /* advanced trigger check trigger_enable */
- ds_trigger_set_en(true);
- }
+ assert(sdi);
+ assert(error_handler);
- sr_session_new();
- sr_session_datafeed_callback_add(data_feed_in_proc, NULL);
-
- if (sr_session_dev_add(sdi) != SR_OK) {
- error_handler(tr("Failed to use device."));
- sr_session_destroy();
- return;
- }
-
- // Set the sample limit
- if (sr_config_set(sdi, SR_CONF_LIMIT_SAMPLES,
- g_variant_new_uint64(record_length)) != SR_OK) {
- error_handler(tr("Failed to configure "
- "time-based sample limit."));
- sr_session_destroy();
- return;
+ if (!_adv_trigger) {
+ /* simple trigger check trigger_enable */
+ ds_trigger_set_en(false);
+ BOOST_FOREACH(const boost::shared_ptr<view::Signal> s, _signals)
+ {
+ assert(s);
+ if (s->get_trig() != 0) {
+ ds_trigger_set_en(true);
+ s->set_trig(s->get_trig());
+ }
}
+ } else {
+ /* advanced trigger check trigger_enable */
+ ds_trigger_set_en(true);
+ }
- receive_data(0);
- set_capture_state(Running);
+ sr_session_new();
+ sr_session_datafeed_callback_add(data_feed_in_proc, NULL);
- if (sr_session_start() != SR_OK) {
- error_handler(tr("Failed to start session."));
- set_capture_state(Stopped);
- return;
- }
+ if (sr_session_dev_add(sdi) != SR_OK) {
+ error_handler(tr("Failed to use device."));
+ sr_session_destroy();
+ return;
+ }
- sr_session_run();
+ // Set the sample limit
+ if (sr_config_set(sdi, SR_CONF_LIMIT_SAMPLES,
+ g_variant_new_uint64(record_length)) != SR_OK) {
+ error_handler(tr("Failed to configure "
+ "time-based sample limit."));
sr_session_destroy();
+ return;
+ }
+
+ receive_data(0);
+ set_capture_state(Running);
+ if (sr_session_start() != SR_OK) {
+ error_handler(tr("Failed to start session."));
set_capture_state(Stopped);
+ return;
+ }
- // Confirm that SR_DF_END was received
- assert(!_cur_logic_snapshot);
- assert(!_cur_analog_snapshot);
+ sr_session_run();
+ sr_session_destroy();
-// g_usleep(3000*1000);
-// }
+ set_capture_state(Stopped);
+
+ // Confirm that SR_DF_END was received
+ assert(!_cur_logic_snapshot);
+ assert(!_cur_dso_snapshot);
+ assert(!_cur_analog_snapshot);
}
void SigSession::feed_in_header(const sr_dev_inst *sdi)
{
- shared_ptr<view::Signal> signal;
+ boost::shared_ptr<view::Signal> signal;
GVariant *gvar;
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
@@ -425,6 +496,10 @@ void SigSession::feed_in_header(const sr_dev_inst *sdi)
logic_probe_count++;
break;
+ case SR_PROBE_DSO:
+ dso_probe_count++;
+ break;
+
case SR_PROBE_ANALOG:
analog_probe_count++;
break;
@@ -443,24 +518,39 @@ 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
{
- lock_guard<mutex> data_lock(_data_mutex);
+ boost::lock_guard<boost::mutex> data_lock(_data_mutex);
if (logic_probe_count != 0) {
_logic_data.reset(new data::Logic(
@@ -471,6 +561,11 @@ void SigSession::feed_in_header(const sr_dev_inst *sdi)
assert(_group_data);
}
+ if (dso_probe_count != 0) {
+ _dso_data.reset(new data::Dso(dso_channel_count, sample_rate));
+ assert(_dso_data);
+ }
+
if (analog_probe_count != 0) {
_analog_data.reset(new data::Analog(analog_probe_count, sample_rate));
assert(_analog_data);
@@ -479,10 +574,10 @@ void SigSession::feed_in_header(const sr_dev_inst *sdi)
// Set Signal data
{
- BOOST_FOREACH(const shared_ptr<view::Signal> s, _signals)
+ BOOST_FOREACH(const boost::shared_ptr<view::Signal> s, _signals)
{
assert(s);
- s->set_data(_logic_data, _analog_data, _group_data);
+ s->set_data(_logic_data, _dso_data, _analog_data, _group_data);
}
receive_data(0);
@@ -503,7 +598,7 @@ void SigSession::add_group()
if (probe_index_list.size() > 1) {
//_group_data.reset(new data::Group(_last_sample_rate));
- const shared_ptr<view::Signal> signal = shared_ptr<view::Signal>(
+ const boost::shared_ptr<view::Signal> signal = boost::shared_ptr<view::Signal>(
new view::GroupSignal("New Group",
_group_data, probe_index_list, _signals.size(), _group_cnt));
_signals.push_back(signal);
@@ -513,7 +608,7 @@ void SigSession::add_group()
if (!_cur_group_snapshot)
{
// Create a new data snapshot
- _cur_group_snapshot = shared_ptr<data::GroupSnapshot>(
+ _cur_group_snapshot = boost::shared_ptr<data::GroupSnapshot>(
new data::GroupSnapshot(_logic_data->get_snapshots().front(), signal->get_index_list()));
//_cur_group_snapshot->append_payload();
_group_data->push_snapshot(_cur_group_snapshot);
@@ -572,7 +667,7 @@ void SigSession::add_protocol(std::list<int> probe_index_list, decoder::Decoder
if (probe_index_list.size() > 0) {
//_group_data.reset(new data::Group(_last_sample_rate));
- const shared_ptr<view::Signal> signal = shared_ptr<view::Signal>(
+ const boost::shared_ptr<view::Signal> signal = boost::shared_ptr<view::Signal>(
new view::ProtocolSignal(decoder->get_decode_name(),
_logic_data, decoder, probe_index_list, 0, _protocol_cnt));
_signals.push_back(signal);
@@ -627,11 +722,18 @@ void SigSession::del_signal(std::vector< boost::shared_ptr<view::Signal> >::iter
void SigSession::init_signals(const sr_dev_inst *sdi)
{
- shared_ptr<view::Signal> signal;
+ boost::shared_ptr<view::Signal> signal;
GVariant *gvar;
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) {
@@ -644,6 +746,10 @@ void SigSession::init_signals(const sr_dev_inst *sdi)
logic_probe_count++;
break;
+ case SR_PROBE_DSO:
+ dso_probe_count++;
+ break;
+
case SR_PROBE_ANALOG:
analog_probe_count++;
break;
@@ -653,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) {
@@ -680,6 +799,11 @@ void SigSession::init_signals(const sr_dev_inst *sdi)
_group_cnt = 0;
}
+ if (dso_probe_count != 0) {
+ _dso_data.reset(new data::Dso(dso_channel_count, sample_rate));
+ assert(_dso_data);
+ }
+
if (analog_probe_count != 0) {
_analog_data.reset(new data::Analog(analog_probe_count, sample_rate));
assert(_analog_data);
@@ -699,13 +823,78 @@ void SigSession::init_signals(const sr_dev_inst *sdi)
switch(probe->type) {
case SR_PROBE_LOGIC:
- signal = shared_ptr<view::Signal>(
+ signal = boost::shared_ptr<view::Signal>(
new view::LogicSignal(probe->name,
_logic_data, probe->index, _signals.size()));
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(), vdiv, timebase, coupling, active));
+ break;
+
case SR_PROBE_ANALOG:
- signal = shared_ptr<view::Signal>(
+ signal = boost::shared_ptr<view::Signal>(
new view::AnalogSignal(probe->name,
_analog_data, probe->index, _signals.size()));
break;
@@ -716,19 +905,27 @@ 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)
{
- shared_ptr<view::Signal> signal;
+ boost::shared_ptr<view::Signal> signal;
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()) {
if (((*i)->get_type() == view::Signal::DS_LOGIC ||
- (*i)->get_type() == view::Signal::DS_ANALOG))
+ (*i)->get_type() == view::Signal::DS_DSO ||
+ (*i)->get_type() == view::Signal::DS_ANALOG))
signals_en_table.insert((*i)->get_index(), 1);
i++;
}
@@ -748,13 +945,78 @@ void SigSession::update_signals(const sr_dev_inst *sdi)
switch(probe->type) {
case SR_PROBE_LOGIC:
- signal = shared_ptr<view::Signal>(
+ signal = boost::shared_ptr<view::Signal>(
new view::LogicSignal(probe->name,
_logic_data, probe->index, 0));
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(), vdiv, timebase, coupling, active));
+ break;
+
case SR_PROBE_ANALOG:
- signal = shared_ptr<view::Signal>(
+ signal = boost::shared_ptr<view::Signal>(
new view::AnalogSignal(probe->name,
_analog_data, probe->index, 0));
break;
@@ -767,7 +1029,8 @@ void SigSession::update_signals(const sr_dev_inst *sdi)
i = _signals.begin();
while (i != _signals.end()) {
if (((*i)->get_type() == view::Signal::DS_LOGIC ||
- (*i)->get_type() == view::Signal::DS_ANALOG) &&
+ (*i)->get_type() == view::Signal::DS_DSO ||
+ (*i)->get_type() == view::Signal::DS_ANALOG) &&
probes_en_table.value((*i)->get_index()) == false) {
std::vector< boost::shared_ptr<view::Signal> >::iterator j = _signals.begin();
while(j != _signals.end()) {
@@ -813,7 +1076,7 @@ void SigSession::feed_in_trigger(const ds_trigger_pos &trigger_pos)
void SigSession::feed_in_logic(const sr_datafeed_logic &logic)
{
- lock_guard<mutex> lock(_data_mutex);
+ boost::lock_guard<boost::mutex> lock(_data_mutex);
if (!_logic_data)
{
@@ -828,7 +1091,7 @@ void SigSession::feed_in_logic(const sr_datafeed_logic &logic)
if (!_cur_logic_snapshot)
{
// Create a new data snapshot
- _cur_logic_snapshot = shared_ptr<data::LogicSnapshot>(
+ _cur_logic_snapshot = boost::shared_ptr<data::LogicSnapshot>(
new data::LogicSnapshot(logic, _total_sample_len, 1));
if (_cur_logic_snapshot->buf_null())
stop_capture();
@@ -845,9 +1108,39 @@ void SigSession::feed_in_logic(const sr_datafeed_logic &logic)
//data_updated();
}
+void SigSession::feed_in_dso(const sr_datafeed_dso &dso)
+{
+ boost::lock_guard<boost::mutex> lock(_data_mutex);
+
+ if(!_dso_data)
+ {
+ qDebug() << "Unexpected dso packet";
+ return; // This dso packet was not expected.
+ }
+
+ if (!_cur_dso_snapshot)
+ {
+ // Create a new data snapshot
+ _cur_dso_snapshot = boost::shared_ptr<data::DsoSnapshot>(
+ new data::DsoSnapshot(dso, _total_sample_len, _dso_data->get_num_probes()));
+ if (_cur_dso_snapshot->buf_null())
+ stop_capture();
+ else
+ _dso_data->push_snapshot(_cur_dso_snapshot);
+ }
+ else
+ {
+ // Append to the existing data snapshot
+ _cur_dso_snapshot->append_payload(dso);
+ }
+
+ receive_data(dso.num_samples);
+ data_updated();
+}
+
void SigSession::feed_in_analog(const sr_datafeed_analog &analog)
{
- lock_guard<mutex> lock(_data_mutex);
+ boost::lock_guard<boost::mutex> lock(_data_mutex);
if(!_analog_data)
{
@@ -858,7 +1151,7 @@ void SigSession::feed_in_analog(const sr_datafeed_analog &analog)
if (!_cur_analog_snapshot)
{
// Create a new data snapshot
- _cur_analog_snapshot = shared_ptr<data::AnalogSnapshot>(
+ _cur_analog_snapshot = boost::shared_ptr<data::AnalogSnapshot>(
new data::AnalogSnapshot(analog, _total_sample_len, _analog_data->get_num_probes()));
if (_cur_analog_snapshot->buf_null())
stop_capture();
@@ -902,6 +1195,11 @@ void SigSession::data_feed_in(const struct sr_dev_inst *sdi,
feed_in_logic(*(const sr_datafeed_logic*)packet->payload);
break;
+ case SR_DF_DSO:
+ assert(packet->payload);
+ feed_in_dso(*(const sr_datafeed_dso*)packet->payload);
+ break;
+
case SR_DF_ANALOG:
assert(packet->payload);
feed_in_analog(*(const sr_datafeed_analog*)packet->payload);
@@ -910,12 +1208,12 @@ void SigSession::data_feed_in(const struct sr_dev_inst *sdi,
case SR_DF_END:
{
{
- lock_guard<mutex> lock(_data_mutex);
- BOOST_FOREACH(const shared_ptr<view::Signal> s, _signals)
+ boost::lock_guard<boost::mutex> lock(_data_mutex);
+ BOOST_FOREACH(const boost::shared_ptr<view::Signal> s, _signals)
{
assert(s);
if (s->get_type() == view::Signal::DS_GROUP) {
- _cur_group_snapshot = shared_ptr<data::GroupSnapshot>(
+ _cur_group_snapshot = boost::shared_ptr<data::GroupSnapshot>(
new data::GroupSnapshot(_logic_data->get_snapshots().front(), s->get_index_list()));
//_cur_group_snapshot->append_payload();
_group_data->push_snapshot(_cur_group_snapshot);
@@ -926,6 +1224,7 @@ void SigSession::data_feed_in(const struct sr_dev_inst *sdi,
}
}
_cur_logic_snapshot.reset();
+ _cur_dso_snapshot.reset();
_cur_analog_snapshot.reset();
}
break;
@@ -975,7 +1274,7 @@ void SigSession::rst_protocol_analyzer(int rst_index, std::list <int > _sel_prob
if (_logic_data)
_decoders.at(rst_index).first->recode(_sel_probes, _options, _options_index);
- BOOST_FOREACH(const shared_ptr<view::Signal> s, _signals)
+ BOOST_FOREACH(const boost::shared_ptr<view::Signal> s, _signals)
{
assert(s);
if (s->get_decoder() == _decoders.at(rst_index).first) {
@@ -992,7 +1291,7 @@ void SigSession::rst_protocol_analyzer(int rst_index, std::list <int > _sel_prob
void SigSession::del_protocol_analyzer(int protocol_index)
{
assert(protocol_index < _decoders.size());
- delete (_decoders.at(protocol_index)).first;
+ //delete (_decoders.at(protocol_index)).first;
// BOOST_FOREACH(const int _index, (_decoders.at(protocol_index)).second) {
// _signals.at(_index)->del_decoder();
@@ -1019,64 +1318,50 @@ QMap<QString, int> SigSession::get_decode_options_index(int decode_index)
/*
* hotplug function
*/
-void SigSession::start_hot_plug_proc(boost::function<void (const QString)> error_handler)
-{
-#ifdef HAVE_LA_DSLOGIC
- if (_hot_plug_handle) {
- error_handler("Hotplug proc have started!");
- return;
- }
+int SigSession::hotplug_callback(struct libusb_context *ctx, struct libusb_device *dev,
+ libusb_hotplug_event event, void *user_data) {
- int ret = libusbhp_init(&_hot_plug_handle);
- if(ret != 0) {
- error_handler("Could not initialize hotplug handle.");
- return;
- }
+ (void)ctx;
+ (void)dev;
+ (void)user_data;
- libusbhp_register_hotplug_listeners(_hot_plug_handle,
- dev_attach_callback,
- dev_detach_callback,
- NULL);
+ if (LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED == event) {
+ _session->_hot_attach = true;
+ qDebug("DSLogic attaced!\n");
+ }else if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == event) {
+ _session->_hot_detach = true;
+ qDebug("DSLogic dettaced!\n");
+ }else{
+ qDebug("Unhandled event %d\n", event);
+ }
- // Begin the session
- _hot_plug.reset(new boost::thread(
- &SigSession::hot_plug_proc, this, error_handler));
-#else
- error_handler("No hotplug device.");
-#endif
+ return 0;
}
-void SigSession::stop_hot_plug_proc()
+void SigSession::hotplug_proc(boost::function<void (const QString)> error_handler)
{
-#ifdef HAVE_LA_DSLOGIC
- if (_hot_plug.get()) {
- _hot_plug->interrupt();
- _hot_plug->join();
- }
- _hot_plug.reset();
+ struct timeval tv;
- if(_hot_plug_handle) {
- libusbhp_exit(_hot_plug_handle);
- _hot_plug_handle = NULL;
- }
-#endif
-}
+ (void)error_handler;
-void SigSession::hot_plug_proc(boost::function<void (const QString)> error_handler)
-{
if (!_sdi)
return;
+ tv.tv_sec = tv.tv_usec = 0;
try {
while(_session) {
+ libusb_handle_events_timeout(NULL, &tv);
if (_hot_attach) {
+ qDebug("DSLogic hardware attached!");
device_attach();
_hot_attach = false;
break;
}
if (_hot_detach) {
+ qDebug("DSLogic hardware detached!");
device_detach();
_logic_data.reset();
+ _dso_data.reset();
_analog_data.reset();
_hot_detach = false;
break;
@@ -1085,39 +1370,51 @@ void SigSession::hot_plug_proc(boost::function<void (const QString)> error_handl
}
} catch(...) {
qDebug("Interrupt exception for hotplug thread was thrown.");
- error_handler("Interrupt exception for hotplug thread was thrown.");
}
qDebug("Hotplug thread exit!");
}
-void SigSession::dev_attach_callback(struct libusbhp_device_t *device, void *user_data)
+void SigSession::register_hotplug_callback()
{
- (void)user_data;
-
- if (device)
- qDebug("Attach: (%04x/%04x)", device->idVendor, device->idProduct);
+ int ret;
+
+ ret = libusb_hotplug_register_callback(NULL, (libusb_hotplug_event)(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |
+ LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT),
+ (libusb_hotplug_flag)LIBUSB_HOTPLUG_ENUMERATE, 0x2A0E, 0x0001,
+ LIBUSB_HOTPLUG_MATCH_ANY, hotplug_callback, NULL,
+ &_hotplug_handle);
+ if (LIBUSB_SUCCESS != ret){
+ qDebug() << "Error creating a hotplug callback\n";
+ }
+}
- _session->_hot_attach = true;
+void SigSession::deregister_hotplug_callback()
+{
+ libusb_hotplug_deregister_callback(NULL, _hotplug_handle);
}
-void SigSession::dev_detach_callback(struct libusbhp_device_t *device, void *user_data)
+void SigSession::start_hotplug_proc(boost::function<void (const QString)> error_handler)
{
- (void)user_data;
- if (device)
- qDebug("Detach: (%04x/%04x)", device->idVendor, device->idProduct);
+ // Begin the session
+ qDebug() << "Starting a hotplug thread...\n";
+ _hot_attach = false;
+ _hot_detach = false;
+ _hotplug.reset(new boost::thread(
+ &SigSession::hotplug_proc, this, error_handler));
- _session->_hot_detach = true;
}
-int SigSession::hot_plug_active()
+void SigSession::stop_hotplug_proc()
{
- if (_hot_plug_handle)
- return 1;
- else
- return 0;
+ if (_hotplug.get()) {
+ _hotplug->interrupt();
+ _hotplug->join();
+ }
+ _hotplug.reset();
}
+
/*
* Tigger
*/
@@ -1126,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
diff --git a/DSLogic-gui/pv/sigsession.h b/DSLogic-gui/pv/sigsession.h
index 9debdea..a8d8cfb 100644
--- a/DSLogic-gui/pv/sigsession.h
+++ b/DSLogic-gui/pv/sigsession.h
@@ -41,6 +41,7 @@
#include <QVariant>
#include <libsigrok4DSLogic/libsigrok.h>
+#include <libusb.h>
namespace pv {
@@ -49,6 +50,8 @@ class DeviceManager;
namespace data {
class Analog;
class AnalogSnapshot;
+class Dso;
+class DsoSnapshot;
class Logic;
class LogicSnapshot;
class Group;
@@ -110,7 +113,7 @@ public:
get_pro_signals();
int get_logic_probe_cnt(const struct sr_dev_inst *sdi);
-
+ int get_dso_probe_cnt(const struct sr_dev_inst *sdi);
int get_analog_probe_cnt(const struct sr_dev_inst *sdi);
void init_signals(const struct sr_dev_inst *sdi);
@@ -147,45 +150,47 @@ public:
std::list<int> get_decode_probes(int decode_index);
QMap<QString, int> get_decode_options_index(int decode_index);
- void start_hot_plug_proc(boost::function<void (const QString)> error_handler);
- void stop_hot_plug_proc();
- int hot_plug_active();
+ void start_hotplug_proc(boost::function<void (const QString)> error_handler);
+ void stop_hotplug_proc();
+ void register_hotplug_callback();
+ void deregister_hotplug_callback();
void set_adv_trigger(bool adv_trigger);
+ 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_logic(const sr_datafeed_logic &logic);
-
+ void feed_in_dso(const sr_datafeed_dso &dso);
void feed_in_analog(const sr_datafeed_analog &analog);
-
void data_feed_in(const struct sr_dev_inst *sdi,
const struct sr_datafeed_packet *packet);
-
static void data_feed_in_proc(const struct sr_dev_inst *sdi,
const struct sr_datafeed_packet *packet, void *cb_data);
- void hot_plug_proc(boost::function<void (const QString)> error_handler);
+ 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);
- static void dev_attach_callback(struct libusbhp_device_t *device, void *user_data);
-
- static void dev_detach_callback(struct libusbhp_device_t *device, void *user_data);
+ void dso_ctrl_proc(boost::function<void (const QString)> error_handler);
private:
DeviceManager &_device_manager;
@@ -208,6 +213,8 @@ private:
mutable boost::mutex _data_mutex;
boost::shared_ptr<data::Logic> _logic_data;
boost::shared_ptr<data::LogicSnapshot> _cur_logic_snapshot;
+ boost::shared_ptr<data::Dso> _dso_data;
+ boost::shared_ptr<data::DsoSnapshot> _cur_dso_snapshot;
boost::shared_ptr<data::Analog> _analog_data;
boost::shared_ptr<data::AnalogSnapshot> _cur_analog_snapshot;
boost::shared_ptr<data::Group> _group_data;
@@ -221,13 +228,18 @@ private:
quint64 _total_sample_len;
- struct libusbhp_t *_hot_plug_handle;
- std::auto_ptr<boost::thread> _hot_plug;
+ libusb_hotplug_callback_handle _hotplug_handle;
+ std::auto_ptr<boost::thread> _hotplug;
bool _hot_attach;
bool _hot_detach;
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);
@@ -246,6 +258,8 @@ signals:
void receive_trigger(quint64 trigger_pos);
+ void dso_ch_changed(uint16_t num);
+
public slots:
diff --git a/DSLogic-gui/pv/toolbars/devicebar.cpp b/DSLogic-gui/pv/toolbars/devicebar.cpp
index 1c49f86..3d38a31 100644
--- a/DSLogic-gui/pv/toolbars/devicebar.cpp
+++ b/DSLogic-gui/pv/toolbars/devicebar.cpp
@@ -31,6 +31,7 @@
#include <QAction>
#include <QDebug>
+#include <QMessageBox>
#include "devicebar.h"
@@ -114,20 +115,20 @@ void DeviceBar::on_device_selected()
void DeviceBar::on_configure()
{
- int dev_mode;
+ int dev_mode, ret;
sr_dev_inst *const sdi = get_selected_device();
assert(sdi);
dev_mode = sdi->mode;
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();
+ ret = dlg.exec();
+ if (ret == QDialog::Accepted) {
+ if (dev_mode != sdi->mode) {
+ device_selected();
+ } else {
+ device_updated();
+ }
}
}
diff --git a/DSLogic-gui/pv/toolbars/devicebar.h b/DSLogic-gui/pv/toolbars/devicebar.h
index 68b555d..c977fb4 100644
--- a/DSLogic-gui/pv/toolbars/devicebar.h
+++ b/DSLogic-gui/pv/toolbars/devicebar.h
@@ -54,7 +54,6 @@ public:
signals:
void device_selected();
-
void device_updated();
private slots:
diff --git a/DSLogic-gui/pv/toolbars/samplingbar.cpp b/DSLogic-gui/pv/toolbars/samplingbar.cpp
index 9c5c2bb..0283939 100644
--- a/DSLogic-gui/pv/toolbars/samplingbar.cpp
+++ b/DSLogic-gui/pv/toolbars/samplingbar.cpp
@@ -27,6 +27,8 @@
#include <boost/foreach.hpp>
+#include <libsigrok4DSLogic/libsigrok.h>
+
#include <QAction>
#include <QDebug>
#include <QLabel>
@@ -63,24 +65,24 @@ const uint64_t SamplingBar::RecordLengths[19] = {
const uint64_t SamplingBar::DefaultRecordLength = 1000000;
const uint64_t SamplingBar::DSLogic_RecordLengths[15] = {
- 1000,
- 2000,
- 5000,
- 10000,
- 20000,
- 50000,
- 100000,
- 200000,
- 500000,
- 1000000,
- 2000000,
- 5000000,
- 10000000,
- 16000000,
- 100000000,
+ 1024,
+ 2048,
+ 4096,
+ 8192,
+ 16384,
+ 32768,
+ 65536,
+ 131072,
+ 262144,
+ 524288,
+ 1048576,
+ 2097152,
+ 4194304,
+ 8388608,
+ 16777216,
};
-const uint64_t SamplingBar::DSLogic_DefaultRecordLength = 16000000;
+const uint64_t SamplingBar::DSLogic_DefaultRecordLength = 16777216;
SamplingBar::SamplingBar(QWidget *parent) :
QToolBar("Sampling Bar", parent),
@@ -106,7 +108,7 @@ SamplingBar::SamplingBar(QWidget *parent) :
// if (l == DefaultRecordLength)
// _record_length_selector.setCurrentIndex(i);
// }
-
+ _record_length_selector.setSizeAdjustPolicy(QComboBox::AdjustToContents);
set_sampling(false);
//_run_stop_button.setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
@@ -131,7 +133,7 @@ void SamplingBar::set_device(struct sr_dev_inst *sdi)
for (size_t i = 0; i < countof(DSLogic_RecordLengths); i++)
{
const uint64_t &l = DSLogic_RecordLengths[i];
- char *const text = sr_si_string_u64(l, " samples");
+ char *const text = sr_iec_string_u64(l, " samples");
_record_length_selector.addItem(QString(text),
qVariantFromValue(l));
g_free(text);
@@ -163,18 +165,47 @@ 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;
const uint64_t *elements = NULL;
gsize num_elements;
- QAction *selector_action = NULL;
+ //QAction *selector_action = NULL;
assert(_sample_rate_list_action);
@@ -205,7 +236,7 @@ void SamplingBar::update_sample_rate_selector()
_sample_rate_list.show();
g_variant_unref(gvar_list);
- selector_action = _sample_rate_list_action;
+ //selector_action = _sample_rate_list_action;
}
g_variant_unref(gvar_dict);
@@ -242,7 +273,9 @@ void SamplingBar::update_sample_rate_selector_value()
void SamplingBar::commit_sample_rate()
{
+ GVariant *gvar;
uint64_t sample_rate = 0;
+ uint64_t last_sample_rate = 0;
assert(_sdi);
@@ -259,12 +292,30 @@ void SamplingBar::commit_sample_rate()
if (sample_rate == 0)
return;
+ // Get last samplerate
+ if (sr_config_get(_sdi->driver, SR_CONF_SAMPLERATE,
+ &gvar, _sdi) != SR_OK) {
+ qDebug() <<
+ "WARNING: Failed to get value of sample rate";
+ return;
+ }
+ last_sample_rate = g_variant_get_uint64(gvar);
+ g_variant_unref(gvar);
+
// Set the samplerate
if (sr_config_set(_sdi, SR_CONF_SAMPLERATE,
g_variant_new_uint64(sample_rate)) != SR_OK) {
qDebug() << "Failed to configure samplerate.";
return;
}
+
+ if (strcmp(_sdi->driver->name, "DSLogic") == 0 && _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)) ||
+ (last_sample_rate != SR_MHZ(400) && sample_rate == SR_MHZ(400)))
+ device_reload();
+ }
}
void SamplingBar::on_sample_rate_changed()
diff --git a/DSLogic-gui/pv/toolbars/samplingbar.h b/DSLogic-gui/pv/toolbars/samplingbar.h
index ddd6c16..d02b8e2 100644
--- a/DSLogic-gui/pv/toolbars/samplingbar.h
+++ b/DSLogic-gui/pv/toolbars/samplingbar.h
@@ -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);
@@ -66,6 +68,7 @@ public:
signals:
void run_stop();
+ void device_reload();
private:
void update_sample_rate_selector_value();
diff --git a/DSLogic-gui/pv/view/analogsignal.cpp b/DSLogic-gui/pv/view/analogsignal.cpp
index 1d86310..2e62bfa 100644
--- a/DSLogic-gui/pv/view/analogsignal.cpp
+++ b/DSLogic-gui/pv/view/analogsignal.cpp
@@ -50,7 +50,7 @@ const QColor AnalogSignal::SignalColours[4] = {
const float AnalogSignal::EnvelopeThreshold = 256.0f;
-AnalogSignal::AnalogSignal(QString name, shared_ptr<data::Analog> data,
+AnalogSignal::AnalogSignal(QString name, boost::shared_ptr<data::Analog> data,
int probe_index, int order) :
Signal(name, probe_index, DS_ANALOG, order),
_data(data)
@@ -64,9 +64,11 @@ AnalogSignal::~AnalogSignal()
}
void AnalogSignal::set_data(boost::shared_ptr<data::Logic> _logic_data,
+ boost::shared_ptr<data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<data::Group> _group_data)
{
+ (void)_dso_data;
(void)_logic_data;
(void)_group_data;
@@ -89,13 +91,13 @@ void AnalogSignal::paint(QPainter &p, int y, int left, int right, double scale,
//paint_axis(p, y, left, right);
- const deque< shared_ptr<pv::data::AnalogSnapshot> > &snapshots =
+ const deque< boost::shared_ptr<pv::data::AnalogSnapshot> > &snapshots =
_data->get_snapshots();
if (snapshots.empty())
return;
_scale = _signalHeight * 1.0f / 65536;
- const shared_ptr<pv::data::AnalogSnapshot> &snapshot =
+ const boost::shared_ptr<pv::data::AnalogSnapshot> &snapshot =
snapshots.front();
if (get_index() >= (int)snapshot->get_channel_num())
@@ -125,7 +127,7 @@ void AnalogSignal::paint(QPainter &p, int y, int left, int right, double scale,
}
void AnalogSignal::paint_trace(QPainter &p,
- const shared_ptr<pv::data::AnalogSnapshot> &snapshot,
+ const boost::shared_ptr<pv::data::AnalogSnapshot> &snapshot,
int y, int left, const int64_t start, const int64_t end,
const double pixels_offset, const double samples_per_pixel)
{
@@ -157,7 +159,7 @@ void AnalogSignal::paint_trace(QPainter &p,
}
void AnalogSignal::paint_envelope(QPainter &p,
- const shared_ptr<pv::data::AnalogSnapshot> &snapshot,
+ const boost::shared_ptr<pv::data::AnalogSnapshot> &snapshot,
int y, int left, const int64_t start, const int64_t end,
const double pixels_offset, const double samples_per_pixel)
{
diff --git a/DSLogic-gui/pv/view/analogsignal.h b/DSLogic-gui/pv/view/analogsignal.h
index fc38a2e..b954487 100644
--- a/DSLogic-gui/pv/view/analogsignal.h
+++ b/DSLogic-gui/pv/view/analogsignal.h
@@ -75,6 +75,7 @@ public:
void del_decoder();
void set_data(boost::shared_ptr<pv::data::Logic> _logic_data,
+ boost::shared_ptr<pv::data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<pv::data::Group> _group_data);
diff --git a/DSLogic-gui/pv/view/dsldial.cpp b/DSLogic-gui/pv/view/dsldial.cpp
new file mode 100644
index 0000000..ccdec2e
--- /dev/null
+++ b/DSLogic-gui/pv/view/dsldial.cpp
@@ -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
diff --git a/DSLogic-gui/pv/view/dsldial.h b/DSLogic-gui/pv/view/dsldial.h
new file mode 100644
index 0000000..6925309
--- /dev/null
+++ b/DSLogic-gui/pv/view/dsldial.h
@@ -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
diff --git a/DSLogic-gui/pv/view/dsosignal.cpp b/DSLogic-gui/pv/view/dsosignal.cpp
new file mode 100644
index 0000000..d11108b
--- /dev/null
+++ b/DSLogic-gui/pv/view/dsosignal.cpp
@@ -0,0 +1,224 @@
+/*
+ * This file is part of the DSLogic-gui project.
+ * DSLogic-gui is based on PulseView.
+ *
+ * Copyright (C) 2013 DreamSourceLab <dreamsourcelab@dreamsourcelab.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#include <extdef.h>
+
+#include <math.h>
+
+#include "dsosignal.h"
+#include "pv/data/dso.h"
+#include "pv/data/dsosnapshot.h"
+
+using namespace boost;
+using namespace std;
+
+namespace pv {
+namespace view {
+
+const QColor DsoSignal::SignalColours[4] = {
+ QColor(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, 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 = _windowHeight * 1.0f / 256;
+ _vDial->set_value(vdiv);
+ _hDial->set_value(timebase);
+ _acCoupling = coupling;
+ _active = active;
+}
+
+DsoSignal::~DsoSignal()
+{
+}
+
+void DsoSignal::set_data(boost::shared_ptr<data::Logic> _logic_data,
+ boost::shared_ptr<data::Dso> _dso_data,
+ boost::shared_ptr<pv::data::Analog> _analog_data,
+ boost::shared_ptr<data::Group> _group_data)
+{
+ (void)_analog_data;
+ (void)_logic_data;
+ (void)_group_data;
+
+ assert(_dso_data);
+
+ _data = _dso_data;
+}
+
+void DsoSignal::set_scale(float scale)
+{
+ _scale = scale;
+}
+
+void DsoSignal::paint(QPainter &p, int y, int left, int right, double scale,
+ double offset)
+{
+ assert(scale > 0);
+ assert(_data);
+ assert(right >= left);
+
+ const deque< boost::shared_ptr<pv::data::DsoSnapshot> > &snapshots =
+ _data->get_snapshots();
+ if (snapshots.empty())
+ return;
+
+ _scale = _windowHeight * 1.0f / 256;
+ const boost::shared_ptr<pv::data::DsoSnapshot> &snapshot =
+ snapshots.front();
+
+ 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 start_time = _data->get_start_time();
+ const int64_t last_sample = max((int64_t)(snapshot->get_sample_count() - 1), (int64_t)0);
+ const double samples_per_pixel = samplerate * scale;
+ const double start = samplerate * (offset - start_time);
+ const double end = start + samples_per_pixel * (right - left);
+
+ const int64_t start_sample = min(max((int64_t)floor(start),
+ (int64_t)0), last_sample);
+ const int64_t end_sample = min(max((int64_t)ceil(end) + 1,
+ (int64_t)0), last_sample);
+
+ if (samples_per_pixel < EnvelopeThreshold)
+ paint_trace(p, snapshot, y, left,
+ start_sample, end_sample,
+ pixels_offset, samples_per_pixel, number_channels);
+ else
+ paint_envelope(p, snapshot, y, left,
+ start_sample, end_sample,
+ pixels_offset, samples_per_pixel);
+}
+
+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, uint64_t num_channels)
+{
+ const int64_t sample_count = end - start;
+
+ if (sample_count > 0) {
+ const uint8_t *const samples = snapshot->get_samples(start, end, get_index());
+ assert(samples);
+
+ p.setPen(_colour);
+ //p.setPen(QPen(_colour, 3, Qt::SolidLine));
+
+ QPointF *points = new QPointF[sample_count];
+ QPointF *point = points;
+
+ for (int64_t sample = start; sample < end; sample++) {
+ const float x = (sample / samples_per_pixel - pixels_offset) + left;
+ uint8_t offset = samples[(sample - start)*num_channels];
+ *point++ = QPointF(x,
+ y - offset * _scale);
+ }
+
+ p.drawPolyline(points, point - points);
+
+ //delete[] samples;
+ delete[] points;
+ }
+}
+
+void DsoSignal::paint_envelope(QPainter &p,
+ const boost::shared_ptr<pv::data::DsoSnapshot> &snapshot,
+ int y, int left, const int64_t start, const int64_t end,
+ const double pixels_offset, const double samples_per_pixel)
+{
+ using namespace Qt;
+ using pv::data::DsoSnapshot;
+
+ DsoSnapshot::EnvelopeSection e;
+ snapshot->get_envelope_section(e, start, end, samples_per_pixel, get_index());
+
+ if (e.length < 2)
+ return;
+
+ p.setPen(QPen(NoPen));
+ //p.setPen(QPen(_colour, 2, Qt::SolidLine));
+ p.setBrush(_colour);
+
+ QRectF *const rects = new QRectF[e.length];
+ QRectF *rect = rects;
+
+ for(uint64_t sample = 0; sample < e.length-1; sample++) {
+ const float x = ((e.scale * sample + e.start) /
+ samples_per_pixel - pixels_offset) + left;
+ const DsoSnapshot::EnvelopeSample *const s =
+ e.samples + sample;
+
+ // We overlap this sample with the next so that vertical
+ // gaps do not appear during steep rising or falling edges
+ const float b = y - max(s->max, (s+1)->min) * _scale;
+ const float t = y - min(s->min, (s+1)->max) * _scale;
+
+ float h = b - t;
+ if(h >= 0.0f && h <= 1.0f)
+ h = 1.0f;
+ if(h <= 0.0f && h >= -1.0f)
+ h = -1.0f;
+
+ *rect++ = QRectF(x, t, 1.0f, h);
+ }
+
+ p.drawRects(rects, e.length);
+
+ delete[] rects;
+ //delete[] e.samples;
+}
+
+const std::vector< std::pair<uint64_t, bool> > DsoSignal::cur_edges() const
+{
+
+}
+
+void DsoSignal::set_decoder(pv::decoder::Decoder *decoder)
+{
+ (void)decoder;
+}
+
+decoder::Decoder *DsoSignal::get_decoder()
+{
+ return NULL;
+}
+
+void DsoSignal::del_decoder()
+{
+}
+
+} // namespace view
+} // namespace pv
diff --git a/DSLogic-gui/pv/view/dsosignal.h b/DSLogic-gui/pv/view/dsosignal.h
new file mode 100644
index 0000000..e22680a
--- /dev/null
+++ b/DSLogic-gui/pv/view/dsosignal.h
@@ -0,0 +1,103 @@
+/*
+ * This file is part of the DSLogic-gui project.
+ * DSLogic-gui is based on PulseView.
+ *
+ * Copyright (C) 2013 DreamSourceLab <dreamsourcelab@dreamsourcelab.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#ifndef DSLOGIC_PV_DSOSIGNAL_H
+#define DSLOGIC_PV_DSOSIGNAL_H
+
+#include "signal.h"
+
+#include <boost/shared_ptr.hpp>
+
+namespace pv {
+
+namespace data {
+class Logic;
+class Dso;
+class Analog;
+class DsoSnapshot;
+}
+
+namespace view {
+
+class DsoSignal : public Signal
+{
+private:
+ static const QColor SignalColours[4];
+
+ static const float EnvelopeThreshold;
+
+public:
+ DsoSignal(QString name,
+ boost::shared_ptr<pv::data::Dso> data, int probe_index, int order,
+ uint64_t vdiv, uint64_t timebase, bool coupling, bool active);
+
+ virtual ~DsoSignal();
+
+ void set_scale(float scale);
+
+ /**
+ * Paints the signal with a QPainter
+ * @param p the QPainter to paint into.
+ * @param y the y-coordinate to draw the signal at.
+ * @param left the x-coordinate of the left edge of the signal.
+ * @param right the x-coordinate of the right edge of the signal.
+ * @param scale the scale in seconds per pixel.
+ * @param offset the time to show at the left hand edge of
+ * the view in seconds.
+ **/
+ void paint(QPainter &p, int y, int left, int right, double scale,
+ double offset);
+
+ const std::vector< std::pair<uint64_t, bool> > cur_edges() const;
+
+ void set_decoder(pv::decoder::Decoder *decoder);
+
+ pv::decoder::Decoder* get_decoder();
+
+ void del_decoder();
+
+ void set_data(boost::shared_ptr<pv::data::Logic> _logic_data,
+ boost::shared_ptr<pv::data::Dso> _dso_data,
+ boost::shared_ptr<pv::data::Analog> _analog_data,
+ boost::shared_ptr<pv::data::Group> _group_data);
+
+private:
+ void paint_trace(QPainter &p,
+ const boost::shared_ptr<pv::data::DsoSnapshot> &snapshot,
+ int y, int left, const int64_t start, const int64_t end,
+ const double pixels_offset, const double samples_per_pixel,
+ uint64_t num_channels);
+
+ void paint_envelope(QPainter &p,
+ const boost::shared_ptr<pv::data::DsoSnapshot> &snapshot,
+ int y, int left, const int64_t start, const int64_t end,
+ const double pixels_offset, const double samples_per_pixel);
+
+private:
+ boost::shared_ptr<pv::data::Dso> _data;
+ float _scale;
+};
+
+} // namespace view
+} // namespace pv
+
+#endif // DSLOGIC_PV_DSOSIGNAL_H
diff --git a/DSLogic-gui/pv/view/groupsignal.cpp b/DSLogic-gui/pv/view/groupsignal.cpp
index 391779c..5330c06 100644
--- a/DSLogic-gui/pv/view/groupsignal.cpp
+++ b/DSLogic-gui/pv/view/groupsignal.cpp
@@ -58,10 +58,12 @@ GroupSignal::~GroupSignal()
}
void GroupSignal::set_data(boost::shared_ptr<data::Logic> _logic_data,
+ boost::shared_ptr<data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<data::Group> _group_data)
{
(void)_logic_data;
+ (void)_dso_data;
(void)_analog_data;
assert(_group_data);
@@ -75,7 +77,7 @@ 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);
@@ -84,12 +86,12 @@ void GroupSignal::paint(QPainter &p, int y, int left, int right, double scale,
_scale = _signalHeight * 1.0f / pow(2, _index_list.size());
paint_axis(p, y, left, right);
- const deque< shared_ptr<pv::data::GroupSnapshot> > &snapshots =
+ const deque< boost::shared_ptr<pv::data::GroupSnapshot> > &snapshots =
_data->get_snapshots();
if (snapshots.empty())
return;
- const shared_ptr<pv::data::GroupSnapshot> &snapshot =
+ const boost::shared_ptr<pv::data::GroupSnapshot> &snapshot =
snapshots.at(_sec_index);
const double pixels_offset = offset / scale;
@@ -116,7 +118,7 @@ void GroupSignal::paint(QPainter &p, int y, int left, int right, double scale,
}
void GroupSignal::paint_trace(QPainter &p,
- const shared_ptr<pv::data::GroupSnapshot> &snapshot,
+ const boost::shared_ptr<pv::data::GroupSnapshot> &snapshot,
int y, int left, const int64_t start, const int64_t end,
const double pixels_offset, const double samples_per_pixel)
{
@@ -144,7 +146,7 @@ void GroupSignal::paint_trace(QPainter &p,
}
void GroupSignal::paint_envelope(QPainter &p,
- const shared_ptr<pv::data::GroupSnapshot> &snapshot,
+ const boost::shared_ptr<pv::data::GroupSnapshot> &snapshot,
int y, int left, const int64_t start, const int64_t end,
const double pixels_offset, const double samples_per_pixel)
{
diff --git a/DSLogic-gui/pv/view/groupsignal.h b/DSLogic-gui/pv/view/groupsignal.h
index 43f858d..d38d1be 100644
--- a/DSLogic-gui/pv/view/groupsignal.h
+++ b/DSLogic-gui/pv/view/groupsignal.h
@@ -79,6 +79,7 @@ public:
void del_decoder();
void set_data(boost::shared_ptr<pv::data::Logic> _logic_data,
+ boost::shared_ptr<pv::data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<pv::data::Group> _group_data);
diff --git a/DSLogic-gui/pv/view/header.cpp b/DSLogic-gui/pv/view/header.cpp
index 9bbea0b..6803e3a 100644
--- a/DSLogic-gui/pv/view/header.cpp
+++ b/DSLogic-gui/pv/view/header.cpp
@@ -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,16 +83,16 @@ 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)
{
const int w = width();
- const vector< shared_ptr<Signal> > sigs(
+ const vector< boost::shared_ptr<Signal> > sigs(
_view.session().get_signals());
const int v_offset = _view.v_offset();
- BOOST_FOREACH(const shared_ptr<Signal> s, sigs)
+ BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs)
{
assert(s);
@@ -108,7 +101,7 @@ boost::shared_ptr<pv::view::Signal> Header::get_mouse_over_signal(
return s;
}
- return shared_ptr<Signal>();
+ return boost::shared_ptr<Signal>();
}
void Header::paintEvent(QPaintEvent*)
@@ -122,7 +115,7 @@ void Header::paintEvent(QPaintEvent*)
const int w = width();
int action;
- const vector< shared_ptr<Signal> > sigs(
+ const vector< boost::shared_ptr<Signal> > sigs(
_view.session().get_signals());
//QPainter painter(this);
@@ -130,7 +123,7 @@ void Header::paintEvent(QPaintEvent*)
const int v_offset = _view.v_offset();
const bool dragging = !_drag_sigs.empty();
- BOOST_FOREACH(const shared_ptr<Signal> s, sigs)
+ BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs)
{
assert(s);
@@ -147,7 +140,7 @@ void Header::paintEvent(QPaintEvent*)
w, s->get_old_v_offset() - v_offset - s->get_signalHeight());
painter.drawLine(0, s->get_old_v_offset() - v_offset,
w, s->get_old_v_offset() - v_offset);
- } else {
+ } else if (s->get_type() == Signal::DS_LOGIC){
painter.drawLine(0, s->get_old_v_offset() - v_offset + 10,
w, s->get_old_v_offset() - v_offset + 10);
}
@@ -157,7 +150,7 @@ void Header::paintEvent(QPaintEvent*)
w, s->get_v_offset() - v_offset);
painter.drawLine(0, s->get_v_offset() - v_offset - s->get_signalHeight(),
w, s->get_v_offset() - v_offset - s->get_signalHeight());
- } else {
+ } else if (s->get_type() == Signal::DS_LOGIC) {
painter.drawLine(0, s->get_v_offset() - v_offset + 10,
w, s->get_v_offset() - v_offset + 10);
}
@@ -171,7 +164,7 @@ void Header::mousePressEvent(QMouseEvent *event)
{
assert(event);
- const vector< shared_ptr<Signal> > sigs(
+ const vector< boost::shared_ptr<Signal> > sigs(
_view.session().get_signals());
int action;
@@ -179,23 +172,24 @@ void Header::mousePressEvent(QMouseEvent *event)
_mouse_down_point = event->pos();
// Save the offsets of any signals which will be dragged
- BOOST_FOREACH(const shared_ptr<Signal> s, sigs)
+ BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs)
if (s->selected())
_drag_sigs.push_back(
make_pair(s, s->get_v_offset()));
// Select the signal if it has been clicked
- const 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 shared_ptr<Signal> s, sigs)
- if (s != mouse_over_signal)
+ BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs)
+ 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 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,12 +318,48 @@ 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;
bool _moveUp = false;
bool firstCheck = true;
- const vector< shared_ptr<Signal> > sigs(
+ const vector< boost::shared_ptr<Signal> > sigs(
_view.session().get_signals());
boost::shared_ptr<Signal> minDragSig;
boost::shared_ptr<Signal> maxDragSig;
@@ -323,7 +407,7 @@ void Header::move(QMouseEvent *event)
}
if (!_moveValid && firstCheck){
firstCheck = false;
- BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
+ BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
if (_moveUp) {
if (s->selected()) {
if ((minOffset <= s->get_old_v_offset()) && (minOffset > (s->get_old_v_offset() - _view.get_spanY()))) {
@@ -360,7 +444,7 @@ void Header::move(QMouseEvent *event)
}
}
if (_moveValid) {
- BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
+ BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
if (_moveUp) {
if (s->selected() && s == minDragSig) {
s->set_v_offset(targetOffset);
@@ -393,7 +477,7 @@ void Header::move(QMouseEvent *event)
if (_moveValid) {
signals_moved();
} else {
- BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
+ BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
if (s->selected()) {
s->set_v_offset(s->get_old_v_offset());
s->select(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 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);
@@ -489,7 +579,7 @@ void Header::contextMenuEvent(QContextMenuEvent *event)
void Header::on_action_set_name_triggered()
{
- shared_ptr<view::Signal> context_signal = _context_signal;
+ boost::shared_ptr<view::Signal> context_signal = _context_signal;
if (!context_signal)
return;
diff --git a/DSLogic-gui/pv/view/header.h b/DSLogic-gui/pv/view/header.h
index 1756278..3e16f27 100644
--- a/DSLogic-gui/pv/view/header.h
+++ b/DSLogic-gui/pv/view/header.h
@@ -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;
diff --git a/DSLogic-gui/pv/view/logicsignal.cpp b/DSLogic-gui/pv/view/logicsignal.cpp
index 5e66bb7..f9fae10 100644
--- a/DSLogic-gui/pv/view/logicsignal.cpp
+++ b/DSLogic-gui/pv/view/logicsignal.cpp
@@ -65,7 +65,7 @@ const QColor LogicSignal::SignalColours[8] = {
const int LogicSignal::StateHeight = 12;
const int LogicSignal::StateRound = 5;
-LogicSignal::LogicSignal(QString name, shared_ptr<data::Logic> data,
+LogicSignal::LogicSignal(QString name, boost::shared_ptr<data::Logic> data,
int probe_index, int order) :
Signal(name, probe_index, DS_LOGIC, order),
_probe_index(probe_index),
@@ -82,9 +82,11 @@ LogicSignal::~LogicSignal()
}
void LogicSignal::set_data(boost::shared_ptr<data::Logic> _logic_data,
+ boost::shared_ptr<data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<data::Group> _group_data)
{
+ (void)_dso_data;
(void)_analog_data;
(void)_group_data;
@@ -110,12 +112,12 @@ void LogicSignal::paint(QPainter &p, int y, int left, int right,
const float high_offset = y - _signalHeight + 0.5f;
const float low_offset = y + 0.5f;
- const deque< shared_ptr<pv::data::LogicSnapshot> > &snapshots =
+ const deque< boost::shared_ptr<pv::data::LogicSnapshot> > &snapshots =
_data->get_snapshots();
if (snapshots.empty())
return;
- const shared_ptr<pv::data::LogicSnapshot> &snapshot =
+ const boost::shared_ptr<pv::data::LogicSnapshot> &snapshot =
snapshots.front();
double samplerate = _data->get_samplerate();
diff --git a/DSLogic-gui/pv/view/logicsignal.h b/DSLogic-gui/pv/view/logicsignal.h
index 39dd388..fa407f2 100644
--- a/DSLogic-gui/pv/view/logicsignal.h
+++ b/DSLogic-gui/pv/view/logicsignal.h
@@ -62,6 +62,7 @@ public:
virtual ~LogicSignal();
void set_data(boost::shared_ptr<pv::data::Logic> _logic_data,
+ boost::shared_ptr<pv::data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<pv::data::Group> _group_data);
/**
diff --git a/DSLogic-gui/pv/view/protocolsignal.cpp b/DSLogic-gui/pv/view/protocolsignal.cpp
index 91834d3..9ad3830 100644
--- a/DSLogic-gui/pv/view/protocolsignal.cpp
+++ b/DSLogic-gui/pv/view/protocolsignal.cpp
@@ -41,7 +41,7 @@ namespace view {
const int ProtocolSignal::StateHeight = 16;
const int ProtocolSignal::StateRound = 3;
-ProtocolSignal::ProtocolSignal(QString name, shared_ptr<data::Logic> data,
+ProtocolSignal::ProtocolSignal(QString name, boost::shared_ptr<data::Logic> data,
pv::decoder::Decoder *decoder, std::list<int> probe_index_list, int order, int protocol_index) :
Signal(name, probe_index_list, DS_PROTOCOL, order, protocol_index),
_probe_index_list(probe_index_list),
@@ -55,10 +55,11 @@ ProtocolSignal::~ProtocolSignal()
{
}
-void ProtocolSignal::set_data(boost::shared_ptr<data::Logic> _logic_data,
+void ProtocolSignal::set_data(boost::shared_ptr<data::Logic> _logic_data, boost::shared_ptr<data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<data::Group> _group_data)
{
+ (void)_dso_data;
(void)_analog_data;
(void)_group_data;
@@ -86,12 +87,12 @@ void ProtocolSignal::paint(QPainter &p, int y, int left, int right, double scale
const float middle_offset = y - _signalHeight / 2 + 0.5f;
//const float low_offset = y + 0.5f;
- const deque< shared_ptr<pv::data::LogicSnapshot> > &snapshots =
+ const deque< boost::shared_ptr<pv::data::LogicSnapshot> > &snapshots =
_data->get_snapshots();
if (snapshots.empty())
return;
- const shared_ptr<pv::data::LogicSnapshot> &snapshot =
+ const boost::shared_ptr<pv::data::LogicSnapshot> &snapshot =
snapshots.front();
double samplerate = _data->get_samplerate();
diff --git a/DSLogic-gui/pv/view/protocolsignal.h b/DSLogic-gui/pv/view/protocolsignal.h
index e608be4..2e37ab8 100644
--- a/DSLogic-gui/pv/view/protocolsignal.h
+++ b/DSLogic-gui/pv/view/protocolsignal.h
@@ -57,6 +57,7 @@ public:
virtual ~ProtocolSignal();
void set_data(boost::shared_ptr<pv::data::Logic> _logic_data,
+ boost::shared_ptr<pv::data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<pv::data::Group> _group_data);
diff --git a/DSLogic-gui/pv/view/ruler.cpp b/DSLogic-gui/pv/view/ruler.cpp
index 1441318..f049beb 100644
--- a/DSLogic-gui/pv/view/ruler.cpp
+++ b/DSLogic-gui/pv/view/ruler.cpp
@@ -99,7 +99,7 @@ QString Ruler::format_freq(double period, unsigned precision)
assert(order >= FirstSIPrefixPower);
const unsigned int prefix = ceil((order - FirstSIPrefixPower) / 3.0f);
const double multiplier = pow(10.0,
- - prefix * 3 - FirstSIPrefixPower);
+ static_cast<double>(- prefix * 3 - FirstSIPrefixPower));
QString s;
QTextStream ts(&s);
@@ -114,7 +114,7 @@ QString Ruler::format_time(double t, unsigned int prefix,
unsigned int precision)
{
const double multiplier = pow(10.0,
- - prefix * 3 - FirstSIPrefixPower);
+ static_cast<double>(- prefix * 3 - FirstSIPrefixPower));
QString s;
QTextStream ts(&s);
@@ -318,7 +318,7 @@ void Ruler::draw_tick_mark(QPainter &p)
//const int order = (int)floorf(log10f(_min_period));
const int order = ceil(log10f(_min_period));
- const double order_decimal = pow(10, order);
+ const double order_decimal = pow(10.0, static_cast<double>(order));
unsigned int unit = 0;
diff --git a/DSLogic-gui/pv/view/signal.cpp b/DSLogic-gui/pv/view/signal.cpp
index 2ac4e92..11ef319 100644
--- a/DSLogic-gui/pv/view/signal.cpp
+++ b/DSLogic-gui/pv/view/signal.cpp
@@ -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 quint64 Signal::vDialValue[Signal::vDialValueCount] = {
+ 5,
+ 10,
+ 20,
+ 50,
+ 100,
+ 200,
+ 500,
+ 1000,
+ 2000,
+ 5000,
+};
+const QString Signal::vDialUnit[Signal::vDialUnitCount] = {
+ "mv",
+ "v",
+};
+
+const quint64 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<quint64> vValue;
+ QVector<QString> vUnit;
+ QVector<quint64> 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<quint64> vValue;
+ QVector<QString> vUnit;
+ QVector<quint64> 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;
+ }
+}
+
+quint64 Signal::get_vDialValue() const
+{
+ return _vDial->get_value();
+}
+
+quint64 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()
- };
-
- p.setPen(Qt::transparent);
- 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));
+ 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);
+ 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));
+
+ 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);
-
- if (color.contains(point))
+ 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) && _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
diff --git a/DSLogic-gui/pv/view/signal.h b/DSLogic-gui/pv/view/signal.h
index f6f8242..8420314 100644
--- a/DSLogic-gui/pv/view/signal.h
+++ b/DSLogic-gui/pv/view/signal.h
@@ -36,12 +36,14 @@
#include <list>
#include "libsigrok4DSLogic/libsigrok.h"
+#include "dsldial.h"
namespace pv {
namespace data {
class SignalData;
class Logic;
+class Dso;
class Analog;
class Group;
}
@@ -55,28 +57,49 @@ namespace view {
class Signal
{
private:
- static const int SquareWidth;
- static const int Margin;
-
- 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 int SquareWidth = 20;
+ static const int Margin = 3;
+ static const int SquareNum = 5;
+
+ static const quint64 vDialValueCount = 10;
+ static const quint64 vDialValueStep = 1000;
+ static const quint64 vDialUnitCount = 2;
+ static const quint64 hDialValueCount = 25;
+ static const quint64 hDialValueStep = 1000;
+ static const quint64 hDialUnitCount = 4;
+ static const quint64 vDialValue[vDialValueCount];
+ static const QString vDialUnit[vDialUnitCount];
+
+ static const quint64 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};
+ enum {DS_LOGIC = 0, DS_ANALOG, DS_GROUP, DS_PROTOCOL, DS_DSO};
protected:
Signal(QString name, int index, int type, int order);
@@ -165,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();
+ quint64 get_vDialValue() const;
+ quint64 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.
@@ -176,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;
@@ -187,6 +236,7 @@ public:
virtual void del_decoder() = 0;
virtual void set_data(boost::shared_ptr<pv::data::Logic> _logic_data,
+ boost::shared_ptr<pv::data::Dso> _dso_data,
boost::shared_ptr<pv::data::Analog> _analog_data,
boost::shared_ptr<pv::data::Group> _group_data) = 0;
@@ -198,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
@@ -219,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:
/**
@@ -237,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;
@@ -264,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
diff --git a/DSLogic-gui/pv/view/view.cpp b/DSLogic-gui/pv/view/view.cpp
index 7d9d8bd..fdd8624 100644
--- a/DSLogic-gui/pv/view/view.cpp
+++ b/DSLogic-gui/pv/view/view.cpp
@@ -27,6 +27,7 @@
#include <boost/foreach.hpp>
+#include <QtGui/QApplication>
#include <QEvent>
#include <QMouseEvent>
#include <QScrollBar>
@@ -104,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);
@@ -175,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() -
@@ -184,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();
@@ -198,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);
@@ -297,14 +321,14 @@ const QPointF& View::hover_point() const
void View::normalize_layout()
{
- const vector< shared_ptr<Signal> > sigs(_session.get_signals());
+ const vector< boost::shared_ptr<Signal> > sigs(_session.get_signals());
int v_min = INT_MAX;
- BOOST_FOREACH(const shared_ptr<Signal> s, sigs)
+ BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs)
v_min = min(s->get_v_offset(), v_min);
const int delta = -min(v_min, 0);
- BOOST_FOREACH(shared_ptr<Signal> s, sigs)
+ BOOST_FOREACH(boost::shared_ptr<Signal> s, sigs)
s->set_v_offset(s->get_v_offset() + delta);
verticalScrollBar()->setSliderPosition(_v_offset + delta);
@@ -324,7 +348,7 @@ int View::get_signalHeight()
void View::get_scroll_layout(double &length, double &offset) const
{
- const shared_ptr<data::SignalData> sig_data = _session.get_data();
+ const boost::shared_ptr<data::SignalData> sig_data = _session.get_data();
if (!sig_data)
return;
@@ -376,12 +400,14 @@ void View::reset_signal_layout()
int offset = SignalMargin + SignalHeight;
_spanY = SignalHeight + 2 * SignalMargin;
- const vector< shared_ptr<Signal> > sigs(_session.get_signals());
- BOOST_FOREACH(shared_ptr<Signal> s, sigs) {
+ 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();
}
@@ -438,10 +464,15 @@ int View::headerWidth()
int maxNameWidth = 0;
int maxLeftWidth = 0;
int maxRightWidth = 0;
+
+ QFont font = QApplication::font();
+ QFontMetrics fm(font);
+ int fontWidth=fm.width("A");
+
const vector< shared_ptr<Signal> > sigs(_session.get_signals());
if (!sigs.empty()){
BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
- maxNameWidth = max(s->get_name().length() * 6, maxNameWidth);
+ maxNameWidth = max(s->get_name().length() * fontWidth, maxNameWidth);
maxLeftWidth = max(s->get_leftWidth(), maxLeftWidth);
maxRightWidth = max(s->get_rightWidth(), maxRightWidth);
}
@@ -512,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();
@@ -549,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;
@@ -568,7 +602,8 @@ void View::marker_time_changed()
void View::on_signals_moved()
{
update_scroll();
- signals_moved();
+ _viewport->update();
+ //signals_moved();
}
/*
@@ -698,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
diff --git a/DSLogic-gui/pv/view/view.h b/DSLogic-gui/pv/view/view.h
index 346e298..61a3eea 100644
--- a/DSLogic-gui/pv/view/view.h
+++ b/DSLogic-gui/pv/view/view.h
@@ -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;
diff --git a/DSLogic-gui/pv/view/viewport.cpp b/DSLogic-gui/pv/view/viewport.cpp
index e0b7e45..9a59aa8 100644
--- a/DSLogic-gui/pv/view/viewport.cpp
+++ b/DSLogic-gui/pv/view/viewport.cpp
@@ -79,9 +79,9 @@ Viewport::Viewport(View &parent) :
int Viewport::get_total_height() const
{
int h = 0;
- const vector< shared_ptr<Signal> > sigs(
+ const vector< boost::shared_ptr<Signal> > sigs(
_view.session().get_signals());
- BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
+ BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
assert(s);
//h = max(s->get_v_offset() + _view.get_signalHeight(), h);
h = max(s->get_v_offset(), h);
@@ -95,7 +95,7 @@ void Viewport::paintEvent(QPaintEvent *event)
(void)event;
using pv::view::Signal;
-
+ int i, j;
QStyleOption o;
o.initFrom(this);
QPainter p(this);
@@ -105,36 +105,35 @@ 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;
- }
- } else if (_view.session().get_device()->mode == ANALOG) {
+ case SigSession::Running:
+ //p.setRenderHint(QPainter::Antialiasing);
+ paintProgress(p);
+ break;
+ }
+ } else {
paintSignals(p);
}
p.setRenderHint(QPainter::Antialiasing, false);
if (_view.get_signalHeight() != _curSignalHeight)
_curSignalHeight = _view.get_signalHeight();
- const vector< shared_ptr<Signal> > sigs(
+ const vector< boost::shared_ptr<Signal> > sigs(
_view.session().get_signals());
- BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
+ BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
assert(s);
//paint_axis(p, y, left, right);
p.setPen(Signal::dsGray);
const double sigY = s->get_v_offset() - _view.v_offset();
- int i, j;
if (s->get_type() == Signal::DS_ANALOG) {
p.drawLine(0, sigY, width(), sigY);
const double spanY = (s->get_signalHeight()) * 1.0f / NumSpanY;
@@ -152,19 +151,47 @@ void Viewport::paintEvent(QPaintEvent *event)
p.drawLine(0 + spanX * i, sigY,
0 + spanX * i, sigY - s->get_signalHeight());
}
- } else {
+ } else if (s->get_type() == Signal::DS_LOGIC) {
p.drawLine(0, sigY + 10, width(), sigY + 10);
}
}
+ if (_view.session().get_device()->mode == DSO) {
+
+ p.setPen(Signal::dsGray);
+ p.setPen(Qt::DotLine);
+
+ const double spanY =height() * 1.0f / 10;
+ for (i = 1; i < 11; i++) {
+ const double posY = spanY * i;
+ p.drawLine(0, posY, width(), posY);
+ const double miniSpanY = spanY / 5;
+ for (j = 1; j < 5; j++) {
+ p.drawLine(width() / 2.0f - 10, posY - miniSpanY * j,
+ width() / 2.0f + 10, posY - miniSpanY * j);
+ }
+ }
+ const double spanX = width() * 1.0f / 10;
+ for (i = 1; i < 11; i++) {
+ const double posX = spanX * i;
+ p.drawLine(posX, 0,
+ posX, height());
+ const double miniSpanX = spanX / 5;
+ for (j = 1; j < 5; j++) {
+ p.drawLine(posX - miniSpanX * j, height() / 2.0f - 10,
+ posX - miniSpanX * j, height() / 2.0f + 10);
+ }
+ }
+ }
+
p.end();
}
void Viewport::paintSignals(QPainter &p)
{
- const vector< shared_ptr<Signal> > sigs(
+ const vector< boost::shared_ptr<Signal> > sigs(
_view.session().get_signals());
-// const vector< shared_ptr<Signal> > pro_sigs(
+// const vector< boost::shared_ptr<Signal> > pro_sigs(
// _view.session().get_pro_signals());
// Plot the signal
const int v_offset = _view.v_offset();
@@ -181,13 +208,14 @@ void Viewport::paintSignals(QPainter &p)
QPainter dbp(&pixmap);
dbp.initFrom(this);
p.setRenderHint(QPainter::Antialiasing, false);
- BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
+ 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 shared_ptr<Signal> s, pro_sigs) {
+// BOOST_FOREACH(const boost::shared_ptr<Signal> s, pro_sigs) {
// assert(s);
// s->paint(dbp, s->get_v_offset() - v_offset, 0, width(),
// _view.scale(), _view.offset());
@@ -196,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();
@@ -364,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();
}
}
@@ -371,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;
@@ -382,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();
}
@@ -445,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();
}
@@ -471,8 +540,8 @@ void Viewport::set_receive_len(quint64 length)
void Viewport::measure()
{
- const vector< shared_ptr<Signal> > sigs(_view.session().get_signals());
- BOOST_FOREACH(const shared_ptr<Signal> s, sigs) {
+ const vector< boost::shared_ptr<Signal> > sigs(_view.session().get_signals());
+ BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
assert(s);
const int curY = _view.hover_point().y();
const double curX = _view.hover_point().x();
diff --git a/DSLogic-gui/pv/view/viewport.h b/DSLogic-gui/pv/view/viewport.h
index 0ecb0c7..c373c78 100644
--- a/DSLogic-gui/pv/view/viewport.h
+++ b/DSLogic-gui/pv/view/viewport.h
@@ -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
diff --git a/DSLogic-gui/res/DSLogic.bin b/DSLogic-gui/res/DSLogic.bin
new file mode 100644
index 0000000..9755839
--- /dev/null
+++ b/DSLogic-gui/res/DSLogic.bin
Binary files differ
diff --git a/DSLogic-gui/res/DSLogic.fw b/DSLogic-gui/res/DSLogic.fw
new file mode 100644
index 0000000..813f8fe
--- /dev/null
+++ b/DSLogic-gui/res/DSLogic.fw
Binary files differ
diff --git a/DSLogic-gui/stylesheet.qss b/DSLogic-gui/stylesheet.qss
index ad91277..7245f27 100644
--- a/DSLogic-gui/stylesheet.qss
+++ b/DSLogic-gui/stylesheet.qss
@@ -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 {
@@ -99,7 +99,7 @@ QComboBox:on { /* shift the text when the popup opens */
QComboBox::drop-down {
subcontrol-origin: padding;
subcontrol-position: top right;
- width: 15px;
+ width: 20px;
border-left-width: 0px;
border-top-right-radius: 4px; /* same radius as the QComboBox */
@@ -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,18 +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;
}
+
QLabel:disabled {
- color: rgb(232, 232, 230, 255);
+ color: rgb(200, 200, 200, 255);
}
QSlider::groove:horizontal {
diff --git a/DSLogic-gui/test/CMakeLists.txt b/DSLogic-gui/test/CMakeLists.txt
index c283171..539ab0d 100644
--- a/DSLogic-gui/test/CMakeLists.txt
+++ b/DSLogic-gui/test/CMakeLists.txt
@@ -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()
+
+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}
+)
+
+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(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
+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
)
-add_definitions(-DBOOST_TEST_DYN_LINK)
+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)
diff --git a/DSLogic-gui/test/COPYING b/DSLogic-gui/test/COPYING
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/DSLogic-gui/test/COPYING
@@ -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>.
diff --git a/DSLogic-gui/test/DSLogic.qrc b/DSLogic-gui/test/DSLogic.qrc
new file mode 100644
index 0000000..d7b5e8a
--- /dev/null
+++ b/DSLogic-gui/test/DSLogic.qrc
@@ -0,0 +1,33 @@
+<RCC>
+ <qresource prefix="/">
+ <file>icons/search.png</file>
+ <file>icons/next.png</file>
+ <file>icons/pre.png</file>
+ <file>icons/file.png</file>
+ <file>icons/photo.png</file>
+ <file>icons/save.png</file>
+ <file>icons/open.png</file>
+ <file>icons/params.png</file>
+ <file>stylesheet.qss</file>
+ <file>icons/down-arrow.png</file>
+ <file>icons/slider-handle.png</file>
+ <file>icons/set.png</file>
+ <file>icons/add.png</file>
+ <file>icons/del.png</file>
+ <file>icons/trigger.png</file>
+ <file>icons/measure.png</file>
+ <file>icons/search-bar.png</file>
+ <file>icons/protocol.png</file>
+ <file>icons/logo_noColor.png</file>
+ <file>icons/logo_color.png</file>
+ <file>icons/logo_muColor.png</file>
+ <file>icons/about.png</file>
+ <file>icons/capture.png</file>
+ <file>icons/stop.png</file>
+ <file>icons/start.png</file>
+ <file>icons/dsl_logo.png</file>
+ <file>icons/logo.png</file>
+ <file>icons/checkbox.png</file>
+ <file>icons/radiobutton.png</file>
+ </qresource>
+</RCC>
diff --git a/DSLogic-gui/test/INSTALL b/DSLogic-gui/test/INSTALL
new file mode 100644
index 0000000..126579b
--- /dev/null
+++ b/DSLogic-gui/test/INSTALL
@@ -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
+
diff --git a/DSLogic-gui/test/NEWS b/DSLogic-gui/test/NEWS
new file mode 100644
index 0000000..e7c2c79
--- /dev/null
+++ b/DSLogic-gui/test/NEWS
@@ -0,0 +1,5 @@
+0.1.0 (2013-12-15)
+------------------
+
+ * Initial release.
+
diff --git a/DSLogic-gui/test/README b/DSLogic-gui/test/README
new file mode 100644
index 0000000..7452797
--- /dev/null
+++ b/DSLogic-gui/test/README
@@ -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
+
diff --git a/DSLogic-gui/config.h b/DSLogic-gui/test/config.h.in
index f6afda9..89868e3 100644
--- a/DSLogic-gui/config.h
+++ b/DSLogic-gui/test/config.h.in
@@ -21,14 +21,14 @@
#define _DSLOGIC_CONFIG_H
/* Application details */
-#define DS_TITLE "DSLogic"
-#define DS_DESCRIPTION "A GUI for DSLogic"
-#define DS_BIN_NAME "DSLogic-gui"
+#define DS_TITLE "@DS_TITLE@"
+#define DS_DESCRIPTION "@DS_DESCRIPTION@"
+#define DS_BIN_NAME "@PROJECT_NAME@"
/* DSLogic version information */
-#define DS_VERSION_MAJOR 0
-#define DS_VERSION_MINOR 1
-#define DS_VERSION_MICRO 0
-#define DS_VERSION_STRING "0.1.0"
+#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
diff --git a/DSLogic-gui/test/extdef.h b/DSLogic-gui/test/extdef.h
new file mode 100644
index 0000000..467b561
--- /dev/null
+++ b/DSLogic-gui/test/extdef.h
@@ -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
diff --git a/DSLogic-gui/test/main.cpp b/DSLogic-gui/test/main.cpp
new file mode 100644
index 0000000..807f3ce
--- /dev/null
+++ b/DSLogic-gui/test/main.cpp
@@ -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;
+}
diff --git a/DSLogic-gui/test/stylesheet.qss b/DSLogic-gui/test/stylesheet.qss
new file mode 100644
index 0000000..7245f27
--- /dev/null
+++ b/DSLogic-gui/test/stylesheet.qss
@@ -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 */