Commit 497e11b16060601dadd1a708ba0e5be1168dee3e

Authored by oliverhaag
1 parent 45738d3a

Two bugfixes, export functionality updated, code simplifications and showing rea…

…l samplerate above scope now
openhantek/ChangeLog
... ... @@ -37,3 +37,11 @@
37 37 2010-08-18 Oliver Haag <oliver.haag@gmail.com>
38 38 * Bugfix: Trigger levels weren't sent to the oscilloscope
39 39 * Implemented single trigger mode
  40 +
  41 +2010-08-22 Oliver Haag <oliver.haag@gmail.com>
  42 +* Bugfix: Pretrigger position wasn't initialized correctly on startup
  43 +* Bugfix: Wrong samplerate values were sent to the oscilloscope
  44 +* Updated exporter class
  45 +* Moved constants.h to dso.h and added functions that return strings for enums
  46 +* Sample buffer size above scope shows real sample count got from oscilloscope
  47 +* Documentation updated
... ...
openhantek/OpenHantek.pro
... ... @@ -24,11 +24,11 @@ SOURCES += src/colorbox.cpp \
24 24 src/settings.cpp \
25 25 src/hantek/control.cpp \
26 26 src/hantek/device.cpp \
27   - src/hantek/types.cpp
  27 + src/hantek/types.cpp \
  28 + src/dso.cpp
28 29 HEADERS += src/colorbox.h \
29 30 src/configdialog.h \
30 31 src/configpages.h \
31   - src/constants.h \
32 32 src/dataanalyzer.h \
33 33 src/dockwindows.h \
34 34 src/dsocontrol.h \
... ... @@ -42,7 +42,8 @@ HEADERS += src/colorbox.h \
42 42 src/settings.h \
43 43 src/hantek/control.h \
44 44 src/hantek/device.h \
45   - src/hantek/types.h
  45 + src/hantek/types.h \
  46 + src/dso.h
46 47  
47 48 # Ressource files
48 49 RESOURCES += res/application.qrc \
... ...
openhantek/mainpage.dox
... ... @@ -10,9 +10,48 @@ OpenHantek is a free software for %Hantek (Voltcraft/Darkwire/Protek/Acetech) US
10 10 You need the development packages for the following libraries to build OpenHantek from source:
11 11 <ul>
12 12 <li><a href="http://qt.nokia.com/">Qt 4</a></li>
13   - <li><a href="http://www.libusb.org/">libusb 0.1.x or 1.x</a></li>
  13 + <li><a href="http://www.libusb.org/">libusb 1.x (or 0.1.x with LIBUSB_VERSION=0)</a></li>
14 14 <li><a href="http://www.fftw.org/">fftw 3</a></li>
15 15 <li><a href="http://www.opengl.org/">OpenGL</a></li>
16 16 </ul>
17 17  
  18 +\subsection ssec_dependencies Building
  19 +After installing these you can build it by running:
  20 +<pre>
  21 + $ qmake
  22 + $ make
  23 + $ make install
  24 +</pre>
  25 +
  26 +\subsection ssec_dependencies Build options
  27 +You can set environment variables to set various build options (Done best by prepending env VARIABLE=value to the qmake command). The known environment variables are:
  28 +<ul>
  29 + <li>
  30 + <b>PREFIX</b><br />
  31 + The installation prefix for make install.
  32 + </li>
  33 + <li>
  34 + <b>LIBUSB_VERSION</b><br />
  35 + The version of the libusb library that should be used. You can switch into libusb 0.1 mode with LIBUSB_VERSION=0.
  36 + </li>
  37 +</ul>
  38 +
  39 +\section sec_firmware Installation of the firmware
  40 +\subsection ssec_drivers Gettings the Windows drivers
  41 +Before using OpenHantek you have to extract the firmware from the official Windows drivers. You can get them from the <a href="http://www.hantek.ru/download.html">Hantek website</a> (<a href="http://translate.google.com/translate?sl=ru&tl=en&u=http%3A%2F%2Fwww.hantek.ru%2F">English translation</a>).
  42 +\subsection ssec_dsoextractfw The firmware extraction tool
  43 +You need the tool dsoextractfw from the sourceforge page too extract the firmware. You have to install libbfd development files and build it by typing:
  44 +<pre>
  45 + $ make
  46 +</pre>
  47 +After building it you have to place the DSO*1.SYS file into the same directory and run the built binary:
  48 +<pre>
  49 + $ ./dsoextractfw
  50 +</pre>
  51 +This should create two .hex files.
  52 +\subsection ssec_firmware Installing the firmware
  53 +Place the extracted .hex files into /usr/local/share/hantekdso/ and copy the 90-hantek-dso.rules file to /etc/udev/rules.d/. To load the firmware you have to install fxload.<br />
  54 +After restarting udev your oscilloscope should be initialized automatically after connecting it to the computer (You have to reconnect it after installing this package).<br />
  55 +If you can't run OpenHantek as normal user, you have too add your user to the plugdev group.
  56 +
18 57 **/
... ...
openhantek/src/configpages.cpp
... ... @@ -274,7 +274,7 @@ DsoConfigScopePage::~DsoConfigScopePage() {
274 274 /// \brief Saves the new settings.
275 275 void DsoConfigScopePage::saveSettings() {
276 276 this->settings->view.antialiasing = this->antialiasingCheckBox->isChecked();
277   - this->settings->view.interpolation = (GlInterpolationMode) this->interpolationComboBox->currentIndex();
  277 + this->settings->view.interpolation = (Dso::InterpolationMode) this->interpolationComboBox->currentIndex();
278 278 this->settings->view.digitalPhosphorDepth = this->digitalPhosphorDepthSpinBox->value();
279 279 }
280 280  
... ...
openhantek/src/configpages.h
... ... @@ -31,7 +31,7 @@
31 31  
32 32  
33 33 #include "dsowidget.h"
34   -#include "constants.h"
  34 +#include "dso.h"
35 35  
36 36  
37 37 class ColorBox;
... ...
openhantek/src/dataanalyzer.cpp
... ... @@ -72,6 +72,12 @@ const AnalyzedData *DataAnalyzer::data(int channel) const {
72 72 return this->analyzedData[channel];
73 73 }
74 74  
  75 +/// \brief Returns the sample count of the analyzed data.
  76 +/// \return The maximum sample count of the last analyzed data.
  77 +unsigned long int DataAnalyzer::sampleCount() {
  78 + return this->maxSamples;
  79 +}
  80 +
75 81 /// \brief Returns the mutex for the data.
76 82 /// \return Mutex for the analyzed data.
77 83 QMutex *DataAnalyzer::mutex() const {
... ... @@ -82,6 +88,8 @@ QMutex *DataAnalyzer::mutex() const {
82 88 void DataAnalyzer::run() {
83 89 this->analyzedDataMutex->lock();
84 90  
  91 + unsigned long int maxSamples = 0;
  92 +
85 93 // Adapt the number of channels for analyzed data
86 94 for(int channel = this->analyzedData.count(); channel < this->settings->scope.voltage.count(); channel++) {
87 95 this->analyzedData.append(new AnalyzedData);
... ... @@ -109,10 +117,13 @@ void DataAnalyzer::run() {
109 117 this->analyzedData[channel]->samples.voltage.interval = 1.0 / this->waitingDataSamplerate;
110 118  
111 119 unsigned int size;
112   - if(channel < this->settings->scope.physicalChannels)
  120 + if(channel < this->settings->scope.physicalChannels) {
113 121 size = this->waitingDataSize[channel];
  122 + if(size > maxSamples)
  123 + maxSamples = size;
  124 + }
114 125 else
115   - size = this->waitingDataSize[0];
  126 + size = maxSamples;
116 127 // Reallocate memory for samples if the sample count has changed
117 128 if(this->analyzedData[channel]->samples.voltage.count != size) {
118 129 this->analyzedData[channel]->samples.voltage.count = size;
... ... @@ -356,6 +367,9 @@ void DataAnalyzer::run() {
356 367 }
357 368 }
358 369  
  370 + this->maxSamples = maxSamples;
  371 + emit(analyzed(maxSamples));
  372 +
359 373 this->analyzedDataMutex->unlock();
360 374 }
361 375  
... ...
openhantek/src/dataanalyzer.h
... ... @@ -30,7 +30,7 @@
30 30 #include <QThread>
31 31  
32 32  
33   -#include "constants.h"
  33 +#include "dso.h"
34 34 #include "helper.h"
35 35  
36 36  
... ... @@ -78,6 +78,7 @@ class DataAnalyzer : public QThread {
78 78 ~DataAnalyzer();
79 79  
80 80 const AnalyzedData *data(int channel) const;
  81 + unsigned long int sampleCount();
81 82 QMutex *mutex() const;
82 83  
83 84 protected:
... ... @@ -88,7 +89,8 @@ class DataAnalyzer : public QThread {
88 89 QList<AnalyzedData *> analyzedData; ///< The analyzed data for each channel
89 90 QMutex *analyzedDataMutex; ///< A mutex for the analyzed data of all channels
90 91  
91   - unsigned int lastBufferSize; ///< The buffer size of the previously analyzed data
  92 + unsigned long int lastBufferSize; ///< The buffer size of the previously analyzed data
  93 + unsigned long int maxSamples; ///< The maximum buffer size of the analyzed data
92 94 Dso::WindowFunction lastWindow; ///< The previously used dft window function
93 95 double *window; ///< The array for the dft window factors
94 96  
... ... @@ -99,6 +101,9 @@ class DataAnalyzer : public QThread {
99 101  
100 102 public slots:
101 103 void analyze(const QList<double *> *data, const QList<unsigned int> *size, double samplerate, QMutex *mutex);
  104 +
  105 + signals:
  106 + void analyzed(unsigned int samples); ///< The data with that much samples has been analyzed
102 107 };
103 108  
104 109 #endif
... ...
openhantek/src/dockwindows.cpp
... ... @@ -58,7 +58,6 @@ HorizontalDock::HorizontalDock(DsoSettings *settings, QWidget *parent, Qt::Windo
58 58 << 1e6 << 2e6 << 5e6 << 1e7; ///< Frequencybase steps in Hz/div
59 59 for(QList<double>::iterator frequencybase = this->frequencybaseSteps.begin(); frequencybase != this->frequencybaseSteps.end(); ++frequencybase)
60 60 this->frequencybaseStrings << Helper::valueToString(*frequencybase, Helper::UNIT_HERTZ, 0);
61   - this->formatStrings << tr("T - Y") << tr("X - Y");
62 61  
63 62 // Initialize elements
64 63 this->timebaseLabel = new QLabel(tr("Timebase"));
... ... @@ -71,7 +70,8 @@ HorizontalDock::HorizontalDock(DsoSettings *settings, QWidget *parent, Qt::Windo
71 70  
72 71 this->formatLabel = new QLabel(tr("Format"));
73 72 this->formatComboBox = new QComboBox();
74   - this->formatComboBox->addItems(this->formatStrings);
  73 + for(int format = Dso::GRAPHFORMAT_TY; format < Dso::GRAPHFORMAT_COUNT; format++)
  74 + this->formatComboBox->addItem(Dso::graphFormatString((Dso::GraphFormat) format));
75 75  
76 76 this->dockLayout = new QGridLayout();
77 77 this->dockLayout->setColumnMinimumWidth(0, 64);
... ... @@ -181,20 +181,20 @@ TriggerDock::TriggerDock(DsoSettings *settings, const QStringList *specialTrigge
181 181 this->settings = settings;
182 182  
183 183 // Initialize lists for comboboxes
184   - this->modeStrings << tr("Auto") << tr("Normal") << tr("Single");
185 184 for(unsigned int channel = 0; channel < this->settings->scope.physicalChannels; channel++)
186 185 this->sourceStandardStrings << tr("CH%1").arg(channel + 1);
187 186 this->sourceSpecialStrings << *specialTriggers;
188   - this->slopeStrings << QString::fromUtf8("\u2197") << QString::fromUtf8("\u2198");
189 187  
190 188 // Initialize elements
191 189 this->modeLabel = new QLabel(tr("Mode"));
192 190 this->modeComboBox = new QComboBox();
193   - this->modeComboBox->addItems(this->modeStrings);
  191 + for(int mode = Dso::TRIGGERMODE_AUTO; mode < Dso::TRIGGERMODE_COUNT; mode++)
  192 + this->modeComboBox->addItem(Dso::triggerModeString((Dso::TriggerMode) mode));
194 193  
195 194 this->slopeLabel = new QLabel(tr("Slope"));
196 195 this->slopeComboBox = new QComboBox();
197   - this->slopeComboBox->addItems(this->slopeStrings);
  196 + for(int slope = Dso::SLOPE_POSITIVE; slope < Dso::SLOPE_COUNT; slope++)
  197 + this->slopeComboBox->addItem(Dso::slopeString((Dso::Slope) slope));
198 198  
199 199 this->sourceLabel = new QLabel(tr("Source"));
200 200 this->sourceComboBox = new QComboBox();
... ... @@ -446,9 +446,11 @@ VoltageDock::VoltageDock(DsoSettings *settings, QWidget *parent, Qt::WindowFlags
446 446 this->settings = settings;
447 447  
448 448 // Initialize lists for comboboxes
449   - this->couplingStrings << tr("AC") << tr("DC") << tr("GND");
  449 + for(int coupling = Dso::COUPLING_AC; coupling < Dso::COUPLING_COUNT; coupling++)
  450 + this->couplingStrings.append(Dso::couplingString((Dso::Coupling) coupling));
450 451  
451   - this->modeStrings << tr("CH1 + CH2") << tr("CH1 - CH2") << tr("CH2 - CH1");
  452 + for(int mode = Dso::MATHMODE_1ADD2; mode < Dso::MATHMODE_COUNT; mode++)
  453 + this->modeStrings.append(Dso::mathModeString((Dso::MathMode) mode));
452 454  
453 455 this->gainSteps << 1e-2 << 2e-2 << 5e-2 << 1e-1 << 2e-1 << 5e-1
454 456 << 1e0 << 2e0 << 5e0; ///< Voltage steps in V/div
... ...
openhantek/src/dockwindows.h
... ... @@ -31,7 +31,7 @@
31 31 #include <QGridLayout>
32 32  
33 33  
34   -#include "constants.h"
  34 +#include "dso.h"
35 35 #include "settings.h"
36 36  
37 37  
... ...
openhantek/src/dso.cpp 0 → 100644
  1 +////////////////////////////////////////////////////////////////////////////////
  2 +//
  3 +// OpenHantek
  4 +// dso.cpp
  5 +//
  6 +// Copyright (C) 2010 Oliver Haag
  7 +// oliver.haag@gmail.com
  8 +//
  9 +// This program is free software: you can redistribute it and/or modify it
  10 +// under the terms of the GNU General Public License as published by the Free
  11 +// Software Foundation, either version 3 of the License, or (at your option)
  12 +// any later version.
  13 +//
  14 +// This program is distributed in the hope that it will be useful, but WITHOUT
  15 +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  16 +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  17 +// more details.
  18 +//
  19 +// You should have received a copy of the GNU General Public License along with
  20 +// this program. If not, see <http://www.gnu.org/licenses/>.
  21 +//
  22 +////////////////////////////////////////////////////////////////////////////////
  23 +
  24 +
  25 +#include <QApplication>
  26 +
  27 +
  28 +#include "dso.h"
  29 +
  30 +
  31 +namespace Dso {
  32 + /// \brief Return string representation of the given channel mode.
  33 + /// \param mode The #ChannelMode that should be returned as string.
  34 + /// \return The string that should be used in labels etc., empty when invalid.
  35 + QString channelModeString(ChannelMode mode) {
  36 + switch(mode) {
  37 + case CHANNELMODE_VOLTAGE:
  38 + return QApplication::tr("Voltage");
  39 + case CHANNELMODE_SPECTRUM:
  40 + return QApplication::tr("Spectrum");
  41 + default:
  42 + return QString();
  43 + }
  44 + }
  45 +
  46 + /// \brief Return string representation of the given graph format.
  47 + /// \param format The #GraphFormat that should be returned as string.
  48 + /// \return The string that should be used in labels etc.
  49 + QString graphFormatString(GraphFormat format) {
  50 + switch(format) {
  51 + case GRAPHFORMAT_TY:
  52 + return QApplication::tr("T - Y");
  53 + case GRAPHFORMAT_XY:
  54 + return QApplication::tr("X - Y");
  55 + default:
  56 + return QString();
  57 + }
  58 + }
  59 +
  60 + /// \brief Return string representation of the given channel coupling.
  61 + /// \param coupling The #Coupling that should be returned as string.
  62 + /// \return The string that should be used in labels etc.
  63 + QString couplingString(Coupling coupling) {
  64 + switch(coupling) {
  65 + case COUPLING_AC:
  66 + return QApplication::tr("AC");
  67 + case COUPLING_DC:
  68 + return QApplication::tr("DC");
  69 + case COUPLING_GND:
  70 + return QApplication::tr("GND");
  71 + default:
  72 + return QString();
  73 + }
  74 + }
  75 +
  76 + /// \brief Return string representation of the given math mode.
  77 + /// \param mode The #MathMode that should be returned as string.
  78 + /// \return The string that should be used in labels etc.
  79 + QString mathModeString(MathMode mode) {
  80 + switch(mode) {
  81 + case MATHMODE_1ADD2:
  82 + return QApplication::tr("CH1 + CH2");
  83 + case MATHMODE_1SUB2:
  84 + return QApplication::tr("CH1 - CH2");
  85 + case MATHMODE_2SUB1:
  86 + return QApplication::tr("CH2 - CH1");
  87 + default:
  88 + return QString();
  89 + }
  90 + }
  91 +
  92 + /// \brief Return string representation of the given trigger mode.
  93 + /// \param mode The #TriggerMode that should be returned as string.
  94 + /// \return The string that should be used in labels etc.
  95 + QString triggerModeString(TriggerMode mode) {
  96 + switch(mode) {
  97 + case TRIGGERMODE_AUTO:
  98 + return QApplication::tr("Auto");
  99 + case TRIGGERMODE_NORMAL:
  100 + return QApplication::tr("Normal");
  101 + case TRIGGERMODE_SINGLE:
  102 + return QApplication::tr("Single");
  103 + default:
  104 + return QString();
  105 + }
  106 + }
  107 +
  108 + /// \brief Return string representation of the given trigger slope.
  109 + /// \param slope The #Slope that should be returned as string.
  110 + /// \return The string that should be used in labels etc.
  111 + QString slopeString(Slope slope) {
  112 + switch(slope) {
  113 + case SLOPE_POSITIVE:
  114 + return QString::fromUtf8("\u2197");
  115 + case SLOPE_NEGATIVE:
  116 + return QString::fromUtf8("\u2198");
  117 + default:
  118 + return QString();
  119 + }
  120 + }
  121 +
  122 + /// \brief Return string representation of the given dft window function.
  123 + /// \param window The #WindowFunction that should be returned as string.
  124 + /// \return The string that should be used in labels etc.
  125 + QString windowFunctionString(WindowFunction window) {
  126 + switch(window) {
  127 + case WINDOW_RECTANGULAR:
  128 + return QApplication::tr("Rectangular");
  129 + case WINDOW_HAMMING:
  130 + return QApplication::tr("Hamming");
  131 + case WINDOW_HANN:
  132 + return QApplication::tr("Hann");
  133 + case WINDOW_COSINE:
  134 + return QApplication::tr("Cosine");
  135 + case WINDOW_LANCZOS:
  136 + return QApplication::tr("Lanczos");
  137 + case WINDOW_BARTLETT:
  138 + return QApplication::tr("Bartlett");
  139 + case WINDOW_TRIANGULAR:
  140 + return QApplication::tr("Triangular");
  141 + case WINDOW_GAUSS:
  142 + return QApplication::tr("Gauss");
  143 + case WINDOW_BARTLETTHANN:
  144 + return QApplication::tr("Bartlett-Hann");
  145 + case WINDOW_BLACKMAN:
  146 + return QApplication::tr("Blackman");
  147 + //case WINDOW_KAISER:
  148 + // return QApplication::tr("Kaiser");
  149 + case WINDOW_NUTTALL:
  150 + return QApplication::tr("Nuttall");
  151 + case WINDOW_BLACKMANHARRIS:
  152 + return QApplication::tr("Blackman-Harris");
  153 + case WINDOW_BLACKMANNUTTALL:
  154 + return QApplication::tr("Blackman-Nuttall");
  155 + case WINDOW_FLATTOP:
  156 + return QApplication::tr("Flat top");
  157 + default:
  158 + return QString();
  159 + }
  160 + }
  161 +
  162 + /// \brief Return string representation of the given graph interpolation mode.
  163 + /// \param interpolation The #InterpolationMode that should be returned as string.
  164 + /// \return The string that should be used in labels etc.
  165 + QString interpolationModeString(InterpolationMode interpolation) {
  166 + switch(interpolation) {
  167 + case INTERPOLATION_OFF:
  168 + return QApplication::tr("Off");
  169 + case INTERPOLATION_LINEAR:
  170 + return QApplication::tr("Linear");
  171 + case INTERPOLATION_SINC:
  172 + return QApplication::tr("Sinc");
  173 + default:
  174 + return QString();
  175 + }
  176 + }
  177 +}
... ...
openhantek/src/constants.h renamed to openhantek/src/dso.h
1 1 ////////////////////////////////////////////////////////////////////////////////
2 2 //
3 3 // OpenHantek
4   -/// \file constants.h
5   -/// \brief Defines global constants and enums.
  4 +/// \file dso.h
  5 +/// \brief Defines various constants, enums and functions for DSO settings.
6 6 //
7 7 // Copyright (C) 2010 Oliver Haag
8 8 // oliver.haag@gmail.com
... ... @@ -23,20 +23,22 @@
23 23 ////////////////////////////////////////////////////////////////////////////////
24 24  
25 25  
26   -#ifndef CONSTANTS_H
27   -#define CONSTANTS_H
  26 +#ifndef DSO_H
  27 +#define DSO_H
  28 +
  29 +
  30 +#include <QString>
28 31  
29 32  
30 33 #define MARKER_COUNT 2 ///< Number of markers
31   -//#define PHYS_CHANNEL_COUNT 2 ///< Number of real channels
32 34  
33 35  
34 36 ////////////////////////////////////////////////////////////////////////////////
35   -/// \namespace Dso constants.h
36   -/// \brief All DSO specific enums for different modes and so on.
  37 +/// \namespace Dso dso.h
  38 +/// \brief All DSO specific things for different modes and so on.
37 39 namespace Dso {
38 40 //////////////////////////////////////////////////////////////////////////////
39   - /// \enum ChannelMode constants.h
  41 + /// \enum ChannelMode dso.h
40 42 /// \brief The channel display modes.
41 43 enum ChannelMode {
42 44 CHANNELMODE_VOLTAGE, ///< Standard voltage view
... ... @@ -45,50 +47,55 @@ namespace Dso {
45 47 };
46 48  
47 49 //////////////////////////////////////////////////////////////////////////////
48   - /// \enum GraphFormat constants.h
  50 + /// \enum GraphFormat dso.h
49 51 /// \brief The possible viewing formats for the graphs on the scope.
50 52 enum GraphFormat {
51 53 GRAPHFORMAT_TY, ///< The standard mode
52   - GRAPHFORMAT_XY ///< CH1 on X-axis, CH2 on Y-axis
  54 + GRAPHFORMAT_XY, ///< CH1 on X-axis, CH2 on Y-axis
  55 + GRAPHFORMAT_COUNT ///< The total number of formats
53 56 };
54 57  
55 58 //////////////////////////////////////////////////////////////////////////////
56   - /// \enum Coupling constants.h
  59 + /// \enum Coupling dso.h
57 60 /// \brief The coupling modes for the channels.
58 61 enum Coupling {
59 62 COUPLING_AC, ///< Offset filtered out by condensator
60 63 COUPLING_DC, ///< No filtering
61   - COUPLING_GND ///< Channel is grounded
  64 + COUPLING_GND, ///< Channel is grounded
  65 + COUPLING_COUNT ///< The total number of coupling modes
62 66 };
63 67  
64 68 //////////////////////////////////////////////////////////////////////////////
65   - /// \enum Slope constants.h
66   - /// \brief The slope that causes a trigger.
67   - enum Slope {
68   - SLOPE_POSITIVE, ///< From lower to higher voltage
69   - SLOPE_NEGATIVE ///< From higher to lower voltage
  69 + /// \enum MathMode dso.h
  70 + /// \brief The different math modes for the math-channel.
  71 + enum MathMode {
  72 + MATHMODE_1ADD2, ///< Add the values of the channels
  73 + MATHMODE_1SUB2, ///< Subtract CH2 from CH1
  74 + MATHMODE_2SUB1, ///< Subtract CH1 from CH2
  75 + MATHMODE_COUNT ///< The total number of math modes
70 76 };
71 77  
72 78 //////////////////////////////////////////////////////////////////////////////
73   - /// \enum TriggerMode constants.h
  79 + /// \enum TriggerMode dso.h
74 80 /// \brief The different triggering modes.
75 81 enum TriggerMode {
76 82 TRIGGERMODE_AUTO, ///< Automatic without trigger event
77 83 TRIGGERMODE_NORMAL, ///< Normal mode
78   - TRIGGERMODE_SINGLE ///< Stop after the first trigger event
  84 + TRIGGERMODE_SINGLE, ///< Stop after the first trigger event
  85 + TRIGGERMODE_COUNT ///< The total number of modes
79 86 };
80 87  
81 88 //////////////////////////////////////////////////////////////////////////////
82   - /// \enum MathMode constants.h
83   - /// \brief The different math modes for the math-channel.
84   - enum MathMode {
85   - MATHMODE_1ADD2, ///< Add the values of the channels
86   - MATHMODE_1SUB2, ///< Subtract CH2 from CH1
87   - MATHMODE_2SUB1 ///< Subtract CH1 from CH2
  89 + /// \enum Slope dso.h
  90 + /// \brief The slope that causes a trigger.
  91 + enum Slope {
  92 + SLOPE_POSITIVE, ///< From lower to higher voltage
  93 + SLOPE_NEGATIVE, ///< From higher to lower voltage
  94 + SLOPE_COUNT ///< Total number of trigger slopes
88 95 };
89 96  
90 97 //////////////////////////////////////////////////////////////////////////////
91   - /// \enum WindowFunction constants.h
  98 + /// \enum WindowFunction dso.h
92 99 /// \brief The supported window functions.
93 100 /// These are needed for spectrum analysis and are applied to the sample values
94 101 /// before calculating the DFT.
... ... @@ -107,18 +114,29 @@ namespace Dso {
107 114 WINDOW_NUTTALL, ///< Nuttall window, cont. first deriv.
108 115 WINDOW_BLACKMANHARRIS, ///< Blackman-Harris window
109 116 WINDOW_BLACKMANNUTTALL, ///< Blackman-Nuttall window
110   - WINDOW_FLATTOP ///< Flat top window
  117 + WINDOW_FLATTOP, ///< Flat top window
  118 + WINDOW_COUNT ///< Total number of window functions
111 119 };
  120 +
  121 + ////////////////////////////////////////////////////////////////////////////////
  122 + /// \enum InterpolationMode dso.h
  123 + /// \brief The different interpolation modes for the graphs.
  124 + enum InterpolationMode {
  125 + INTERPOLATION_OFF = 0, ///< Just dots for each sample
  126 + INTERPOLATION_LINEAR, ///< Sample dots connected by lines
  127 + INTERPOLATION_SINC, ///< Smooth graph through the dots
  128 + INTERPOLATION_COUNT ///< Total number of interpolation modes
  129 + };
  130 +
  131 + QString channelModeString(ChannelMode mode);
  132 + QString graphFormatString(GraphFormat format);
  133 + QString couplingString(Coupling coupling);
  134 + QString mathModeString(MathMode mode);
  135 + QString triggerModeString(TriggerMode mode);
  136 + QString slopeString(Slope slope);
  137 + QString windowFunctionString(WindowFunction window);
  138 + QString interpolationModeString(InterpolationMode interpolation);
112 139 }
113 140  
114   -////////////////////////////////////////////////////////////////////////////////
115   -/// \enum GlInterpolationMode constants.h
116   -/// \brief The different interpolation modes for the graphs.
117   -enum GlInterpolationMode {
118   - INTERPOLATION_OFF = 0, ///< Just dots for each sample
119   - INTERPOLATION_LINEAR, ///< Sample dots connected by lines
120   - INTERPOLATION_SINC ///< Smooth graph through the dots
121   -};
122   -
123 141  
124 142 #endif
... ...
openhantek/src/dsocontrol.h
... ... @@ -31,7 +31,7 @@
31 31 #include <QThread>
32 32  
33 33  
34   -#include "constants.h"
  34 +#include "dso.h"
35 35 #include "helper.h"
36 36  
37 37  
... ... @@ -72,7 +72,7 @@ class DsoControl : public QThread {
72 72 virtual void stopSampling();
73 73  
74 74 virtual unsigned long int setSamplerate(unsigned long int samplerate) = 0; ///< Set the samplerate that should be met
75   - virtual double setBufferSize(unsigned int size) = 0; ///< Set the needed buffer size
  75 + virtual unsigned long int setBufferSize(unsigned long int size) = 0; ///< Set the needed buffer size
76 76  
77 77 virtual int setTriggerMode(Dso::TriggerMode mode) = 0; ///< Set the trigger mode
78 78 virtual int setTriggerSource(bool special, unsigned int id) = 0; ///< Set the trigger source
... ...
openhantek/src/dsowidget.cpp
... ... @@ -31,6 +31,7 @@
31 31 #include "dsowidget.h"
32 32  
33 33 #include "dataanalyzer.h"
  34 +#include "dso.h"
34 35 #include "exporter.h"
35 36 #include "glscope.h"
36 37 #include "helper.h"
... ... @@ -224,7 +225,7 @@ DsoWidget::DsoWidget(DsoSettings *settings, DataAnalyzer *dataAnalyzer, QWidget
224 225  
225 226 // Apply settings and update measured values
226 227 this->updateTriggerDetails();
227   - this->updateBufferSize();
  228 + this->updateBufferSize(this->settings->scope.horizontal.samples);
228 229 this->updateFrequencybase();
229 230 this->updateTimebase();
230 231 this->updateZoom(this->settings->view.zoom);
... ... @@ -244,7 +245,8 @@ DsoWidget::DsoWidget(DsoSettings *settings, DataAnalyzer *dataAnalyzer, QWidget
244 245 this->connect(this->markerSlider, SIGNAL(valueChanged(int, double)), this->zoomScope, SLOT(updateGL()));
245 246  
246 247 // Connect other signals
247   - this->connect(this->dataAnalyzer, SIGNAL(finished()), this, SLOT(dataAnalyzed()));
  248 + this->connect(this->dataAnalyzer, SIGNAL(analyzed(unsigned int)), this, SLOT(dataAnalyzed()));
  249 + this->connect(this->dataAnalyzer, SIGNAL(analyzed(unsigned int)), this, SLOT(updateBufferSize(unsigned int)));
248 250 }
249 251  
250 252 /// \brief Stops the oscilloscope thread and the timer.
... ... @@ -303,15 +305,9 @@ void DsoWidget::updateTriggerDetails() {
303 305 QPalette tablePalette = this->palette();
304 306 tablePalette.setColor(QPalette::WindowText, this->settings->view.color.screen.voltage[this->settings->scope.trigger.source]);
305 307 this->settingsTriggerLabel->setPalette(tablePalette);
306   - QString slopeString;
307   - if(this->settings->scope.trigger.slope == Dso::SLOPE_POSITIVE)
308   - slopeString = QString::fromUtf8("\u2197");
309   - else
310   - slopeString = QString::fromUtf8("\u2198");
311   - QString levelString;
312   - levelString = Helper::valueToString(this->settings->scope.voltage[this->settings->scope.trigger.source].trigger, Helper::UNIT_VOLTS, 3);
  308 + QString levelString = Helper::valueToString(this->settings->scope.voltage[this->settings->scope.trigger.source].trigger, Helper::UNIT_VOLTS, 3);
313 309 QString pretriggerString = tr("%L1%").arg((int) (this->settings->scope.trigger.position * 100 + 0.5));
314   - this->settingsTriggerLabel->setText(tr("%1 %2 %3 %4").arg(this->settings->scope.voltage[this->settings->scope.trigger.source].name, slopeString, levelString, pretriggerString));
  310 + this->settingsTriggerLabel->setText(tr("%1 %2 %3 %4").arg(this->settings->scope.voltage[this->settings->scope.trigger.source].name, Dso::slopeString(this->settings->scope.trigger.slope), levelString, pretriggerString));
315 311  
316 312 /// \todo This won't work for special trigger sources
317 313 }
... ... @@ -394,36 +390,14 @@ void DsoWidget::updateVoltageCoupling(unsigned int channel) {
394 390 if(channel >= (unsigned int) this->settings->scope.voltage.count())
395 391 return;
396 392  
397   - if(this->settings->scope.voltage[channel].used || this->settings->scope.spectrum[channel].used) {
398   - switch(this->settings->scope.voltage[channel].misc) {
399   - case Dso::COUPLING_AC:
400   - this->measurementMiscLabel[channel]->setText(tr("AC"));
401   - break;
402   - case Dso::COUPLING_DC:
403   - this->measurementMiscLabel[channel]->setText(tr("DC"));
404   - break;
405   - case Dso::COUPLING_GND:
406   - this->measurementMiscLabel[channel]->setText(tr("GND"));
407   - break;
408   - }
409   - }
  393 + if(this->settings->scope.voltage[channel].used || this->settings->scope.spectrum[channel].used)
  394 + this->measurementMiscLabel[channel]->setText(Dso::couplingString((Dso::Coupling) this->settings->scope.voltage[channel].misc));
410 395 }
411 396  
412 397 /// \brief Handles modeChanged signal from the voltage dock.
413 398 void DsoWidget::updateMathMode() {
414   - if(this->settings->scope.voltage[this->settings->scope.physicalChannels].used || this->settings->scope.spectrum[this->settings->scope.physicalChannels].used) {
415   - switch(this->settings->scope.voltage[this->settings->scope.physicalChannels].misc) {
416   - case Dso::MATHMODE_1ADD2:
417   - this->measurementMiscLabel[this->settings->scope.physicalChannels]->setText(tr("CH1 + CH2"));
418   - break;
419   - case Dso::MATHMODE_1SUB2:
420   - this->measurementMiscLabel[this->settings->scope.physicalChannels]->setText(tr("CH1 - CH2"));
421   - break;
422   - case Dso::MATHMODE_2SUB1:
423   - this->measurementMiscLabel[this->settings->scope.physicalChannels]->setText(tr("CH2 - CH1"));
424   - break;
425   - }
426   - }
  399 + if(this->settings->scope.voltage[this->settings->scope.physicalChannels].used || this->settings->scope.spectrum[this->settings->scope.physicalChannels].used)
  400 + this->measurementMiscLabel[this->settings->scope.physicalChannels]->setText(Dso::mathModeString((Dso::MathMode) this->settings->scope.voltage[this->settings->scope.physicalChannels].misc));
427 401 }
428 402  
429 403 /// \brief Handles gainChanged signal from the voltage dock.
... ... @@ -453,8 +427,8 @@ void DsoWidget::updateVoltageUsed(unsigned int channel, bool used) {
453 427 }
454 428  
455 429 /// \brief Change the buffer size.
456   -void DsoWidget::updateBufferSize() {
457   - this->settingsBufferLabel->setText(tr("%1 S").arg(this->settings->scope.horizontal.samples));
  430 +void DsoWidget::updateBufferSize(unsigned int size) {
  431 + this->settingsBufferLabel->setText(tr("%1 S").arg(size));
458 432 }
459 433  
460 434 /// \brief Export the oscilloscope screen to a file.
... ...
openhantek/src/dsowidget.h
... ... @@ -116,7 +116,7 @@ class DsoWidget : public QWidget {
116 116 void updateVoltageUsed(unsigned int channel, bool used);
117 117  
118 118 // Menus
119   - void updateBufferSize();
  119 + void updateBufferSize(unsigned int size);
120 120  
121 121 // Export
122 122 bool exportAs();
... ...
openhantek/src/exporter.cpp
... ... @@ -23,6 +23,7 @@
23 23  
24 24  
25 25 #include <QImage>
  26 +#include <QMutex>
26 27 #include <QPainter>
27 28 #include <QPixmap>
28 29 #include <QPrintDialog>
... ... @@ -32,7 +33,8 @@
32 33 #include "exporter.h"
33 34  
34 35 #include "dataanalyzer.h"
35   -#include "glscope.h"
  36 +#include "dso.h"
  37 +#include "glgenerator.h"
36 38 #include "helper.h"
37 39 #include "settings.h"
38 40  
... ... @@ -84,7 +86,7 @@ bool Exporter::doExport() {
84 86 if(this->format < EXPORT_FORMAT_IMAGE) {
85 87 // We need a QPrinter for printing, pdf- and ps-export
86 88 paintDevice = new QPrinter(QPrinter::HighResolution);
87   - ((QPrinter *) paintDevice)->setOrientation(QPrinter::Landscape);
  89 + ((QPrinter *) paintDevice)->setOrientation(this->settings->view.zoom ? QPrinter::Portrait : QPrinter::Landscape);
88 90 ((QPrinter *) paintDevice)->setPageMargins(20, 20, 20, 20, QPrinter::Millimeter);
89 91  
90 92 if(this->format == EXPORT_FORMAT_PRINTER) {
... ... @@ -113,39 +115,69 @@ bool Exporter::doExport() {
113 115 QFont font;
114 116 QFontMetrics fontMetrics(font, paintDevice);
115 117 double lineHeight = fontMetrics.height();
116   - double valueColumnWidth = (double) (paintDevice->width() - lineHeight * 4) / 2;
117 118  
118 119 painter.setBrush(Qt::SolidPattern);
119 120  
  121 + this->dataAnalyzer->mutex()->lock();
  122 +
  123 + // Draw the settings table
  124 + double stretchBase = (double) (paintDevice->width() - lineHeight * 10) / 4;
  125 +
  126 + // Print trigger details
  127 + painter.setPen(colorValues->voltage[this->settings->scope.trigger.source]);
  128 + QString levelString = Helper::valueToString(this->settings->scope.voltage[this->settings->scope.trigger.source].trigger, Helper::UNIT_VOLTS, 3);
  129 + QString pretriggerString = tr("%L1%").arg((int) (this->settings->scope.trigger.position * 100 + 0.5));
  130 + painter.drawText(QRectF(0, 0, lineHeight * 10, lineHeight), tr("%1 %2 %3 %4").arg(this->settings->scope.voltage[this->settings->scope.trigger.source].name, Dso::slopeString(this->settings->scope.trigger.slope), levelString, pretriggerString));
  131 +
  132 + // Print sample count
  133 + painter.setPen(colorValues->text);
  134 + painter.drawText(QRectF(lineHeight * 10, 0, stretchBase, lineHeight), tr("%1 S").arg(this->dataAnalyzer->sampleCount()), QTextOption(Qt::AlignRight));
  135 + // Print samplerate
  136 + painter.drawText(QRectF(lineHeight * 10 + stretchBase, 0, stretchBase, lineHeight), Helper::valueToString(this->settings->scope.horizontal.samplerate, Helper::UNIT_SAMPLES) + tr("/s"), QTextOption(Qt::AlignRight));
  137 + // Print timebase
  138 + painter.drawText(QRectF(lineHeight * 10 + stretchBase * 2, 0, stretchBase, lineHeight), Helper::valueToString(this->settings->scope.horizontal.timebase, Helper::UNIT_SECONDS, 0) + tr("/div"), QTextOption(Qt::AlignRight));
  139 + // Print frequencybase
  140 + painter.drawText(QRectF(lineHeight * 10 + stretchBase * 3, 0, stretchBase, lineHeight), Helper::valueToString(this->settings->scope.horizontal.frequencybase, Helper::UNIT_HERTZ, 0) + tr("/div"), QTextOption(Qt::AlignRight));
  141 +
  142 + // Draw the measurement table
  143 + stretchBase = (double) (paintDevice->width() - lineHeight * 6) / 10;
120 144 int channelCount = 0;
121 145 for(int channel = 0; channel < this->settings->scope.voltage.count(); channel++) {
122   - if(this->settings->scope.voltage[channel].used) {
  146 + if(this->settings->scope.voltage[channel].used || this->settings->scope.spectrum[channel].used) {
123 147 channelCount++;
124 148 double top = (double) paintDevice->height() - channelCount * lineHeight;
125 149  
126   - painter.setPen(colorValues->voltage[channel]);
127   -
128 150 // Print label
  151 + painter.setPen(colorValues->voltage[channel]);
129 152 painter.drawText(QRectF(0, top, lineHeight * 4, lineHeight), this->settings->scope.voltage[channel].name);
  153 + // Print coupling/math mode
  154 + if((unsigned int) channel < this->settings->scope.physicalChannels)
  155 + painter.drawText(QRectF(lineHeight * 4, top, lineHeight * 2, lineHeight), Dso::couplingString((Dso::Coupling) this->settings->scope.voltage[channel].misc));
  156 + else
  157 + painter.drawText(QRectF(lineHeight * 4, top, lineHeight * 2, lineHeight), Dso::mathModeString((Dso::MathMode) this->settings->scope.voltage[channel].misc));
  158 +
  159 + // Print voltage gain
  160 + painter.drawText(QRectF(lineHeight * 6, top, stretchBase * 2, lineHeight), Helper::valueToString(this->settings->scope.voltage[channel].gain, Helper::UNIT_VOLTS, 0) + tr("/div"), QTextOption(Qt::AlignRight));
  161 + // Print spectrum magnitude
  162 + painter.setPen(colorValues->spectrum[channel]);
  163 + painter.drawText(QRectF(lineHeight * 6 + stretchBase * 2, top, stretchBase * 2, lineHeight), Helper::valueToString(this->settings->scope.spectrum[channel].magnitude, Helper::UNIT_DECIBEL, 0) + tr("/div"), QTextOption(Qt::AlignRight));
130 164  
131 165 // Amplitude string representation (4 significant digits)
132   - painter.drawText(QRectF(lineHeight * 4, top, valueColumnWidth, lineHeight), Helper::valueToString(this->dataAnalyzer->data(channel)->amplitude, Helper::UNIT_VOLTS, 4), QTextOption(Qt::AlignRight));
  166 + painter.setPen(colorValues->text);
  167 + painter.drawText(QRectF(lineHeight * 6 + stretchBase * 4, top, stretchBase * 3, lineHeight), Helper::valueToString(this->dataAnalyzer->data(channel)->amplitude, Helper::UNIT_VOLTS, 4), QTextOption(Qt::AlignRight));
133 168 // Frequency string representation (5 significant digits)
134   - painter.drawText(QRectF(lineHeight * 4 + valueColumnWidth, top, valueColumnWidth, lineHeight), Helper::valueToString(this->dataAnalyzer->data(channel)->frequency, Helper::UNIT_HERTZ, 5), QTextOption(Qt::AlignRight));
  169 + painter.drawText(QRectF(lineHeight * 6 + stretchBase * 7, top, stretchBase * 3, lineHeight), Helper::valueToString(this->dataAnalyzer->data(channel)->frequency, Helper::UNIT_HERTZ, 5), QTextOption(Qt::AlignRight));
135 170 }
136 171 }
137 172  
138 173 // Set DIVS_TIME x DIVS_VOLTAGE matrix for oscillograph
139   - double screenHeight = (double) paintDevice->height() - (channelCount + 1) * lineHeight;
140   - painter.setMatrix(QMatrix((paintDevice->width() - 1) / DIVS_TIME, 0, 0, -(screenHeight - 1) / DIVS_VOLTAGE, (double) (paintDevice->width() - 1) / 2, (screenHeight - 1) / 2), false);
141   -
  174 + double screenHeight = (double) paintDevice->height() - (channelCount + 3) * lineHeight;
  175 + painter.setMatrix(QMatrix((paintDevice->width() - 1) / DIVS_TIME, 0, 0, -(screenHeight - 1) / DIVS_VOLTAGE, (double) (paintDevice->width() - 1) / 2, (screenHeight - 1) / 2 + lineHeight * 2), false);
142 176  
143 177 // Draw the graphs
144 178 painter.setRenderHint(QPainter::Antialiasing);
145 179 painter.setBrush(Qt::NoBrush);
146 180  
147   - this->dataAnalyzer->mutex()->lock();
148   -
149 181 switch(this->settings->scope.horizontal.format) {
150 182 case Dso::GRAPHFORMAT_TY:
151 183 // Add graphs for channels
... ... @@ -191,6 +223,9 @@ bool Exporter::doExport() {
191 223  
192 224 case Dso::GRAPHFORMAT_XY:
193 225 break;
  226 +
  227 + default:
  228 + break;
194 229 }
195 230  
196 231 this->dataAnalyzer->mutex()->unlock();
... ...
openhantek/src/glgenerator.cpp
... ... @@ -223,6 +223,9 @@ void GlGenerator::generateGraphs() {
223 223 this->vaChannel[Dso::CHANNELMODE_SPECTRUM][channel][index]->setSize(0);
224 224 }
225 225 break;
  226 +
  227 + default:
  228 + break;
226 229 }
227 230  
228 231 this->dataAnalyzer->mutex()->unlock();
... ...
openhantek/src/glgenerator.h
... ... @@ -34,7 +34,7 @@
34 34 #include <QObject>
35 35  
36 36  
37   -#include "constants.h"
  37 +#include "dso.h"
38 38  
39 39  
40 40 #define DIVS_TIME 10.0 ///< Number of horizontal screen divs
... ...
openhantek/src/glscope.cpp
... ... @@ -113,7 +113,7 @@ void GlScope::paintGL() {
113 113 else
114 114 this->qglColor(this->settings->view.color.screen.spectrum[channel].darker(fadingFactor[index]));
115 115 glVertexPointer(2, GL_FLOAT, 0, this->generator->vaChannel[mode][channel][index]->data);
116   - glDrawArrays((this->settings->view.interpolation == INTERPOLATION_OFF) ? GL_POINTS : GL_LINE_STRIP, 0, this->generator->vaChannel[mode][channel][index]->getSize() / 2);
  116 + glDrawArrays((this->settings->view.interpolation == Dso::INTERPOLATION_OFF) ? GL_POINTS : GL_LINE_STRIP, 0, this->generator->vaChannel[mode][channel][index]->getSize() / 2);
117 117 }
118 118 }
119 119 }
... ... @@ -130,12 +130,15 @@ void GlScope::paintGL() {
130 130 if(this->generator->vaChannel[Dso::CHANNELMODE_VOLTAGE][channel][index]->data) {
131 131 this->qglColor(this->settings->view.color.screen.voltage[channel].darker(fadingFactor[index]));
132 132 glVertexPointer(2, GL_FLOAT, 0, this->generator->vaChannel[Dso::CHANNELMODE_VOLTAGE][channel][index]->data);
133   - glDrawArrays((this->settings->view.interpolation == INTERPOLATION_OFF) ? GL_POINTS : GL_LINE_STRIP, 0, this->generator->vaChannel[Dso::CHANNELMODE_VOLTAGE][channel][index]->getSize() / 2);
  133 + glDrawArrays((this->settings->view.interpolation == Dso::INTERPOLATION_OFF) ? GL_POINTS : GL_LINE_STRIP, 0, this->generator->vaChannel[Dso::CHANNELMODE_VOLTAGE][channel][index]->getSize() / 2);
134 134 }
135 135 }
136 136 }
137 137 }
138 138 break;
  139 +
  140 + default:
  141 + break;
139 142 }
140 143  
141 144 delete[] fadingFactor;
... ...
openhantek/src/glscope.h
... ... @@ -33,7 +33,7 @@
33 33  
34 34  
35 35 #include "glgenerator.h"
36   -#include "constants.h"
  36 +#include "dso.h"
37 37  
38 38  
39 39 class DataAnalyzer;
... ...
openhantek/src/hantek/control.cpp
... ... @@ -86,7 +86,7 @@ namespace Hantek {
86 86 this->setSamplerate(1e6);
87 87 this->setBufferSize(BUFFER_SMALL);
88 88 this->setTriggerMode(Dso::TRIGGERMODE_NORMAL);
89   - this->setTriggerPosition(0.5);
  89 + this->setTriggerPosition(5e3 / this->samplerateSteps[this->samplerate]);
90 90 this->setTriggerSlope(Dso::SLOPE_POSITIVE);
91 91 this->setTriggerSource(false, 0);
92 92  
... ... @@ -411,19 +411,31 @@ namespace Hantek {
411 411 return 0;
412 412 }
413 413  
414   - /// \brief Sets the size of the oscilloscopes sample buffer.
  414 + /// \brief Sets the size of the sample buffer without updating dependencies.
415 415 /// \param size The buffer size that should be met (S).
416 416 /// \return The buffer size that has been set.
417   - double Control::setBufferSize(unsigned int size) {
  417 + unsigned long int Control::updateBufferSize(unsigned long int size) {
418 418 unsigned int sizeId = (size <= BUFFER_SMALL) ? 1 : 2;
419 419  
420 420 // SetTriggerAndSamplerate bulk command for samplerate
421 421 ((CommandSetTriggerAndSamplerate *) this->command[COMMAND_SETTRIGGERANDSAMPLERATE])->setSampleSize(sizeId);
422 422 this->commandPending[COMMAND_SETTRIGGERANDSAMPLERATE] = true;
423 423  
  424 + this->bufferSize = (sizeId == 1) ? BUFFER_SMALL : BUFFER_LARGE;
  425 +
  426 + return this->bufferSize;
  427 + }
  428 +
  429 + /// \brief Sets the size of the oscilloscopes sample buffer.
  430 + /// \param size The buffer size that should be met (S).
  431 + /// \return The buffer size that has been set.
  432 + unsigned long int Control::setBufferSize(unsigned long int size) {
  433 + this->updateBufferSize(size);
  434 +
  435 + this->setTriggerPosition(this->triggerPosition);
424 436 this->setSamplerate(this->samplerateSteps[this->samplerate]);
  437 + this->setTriggerSlope(this->triggerSlope);
425 438  
426   - this->bufferSize = (sizeId == 1) ? BUFFER_SMALL : BUFFER_LARGE;
427 439 return this->bufferSize;
428 440 }
429 441  
... ... @@ -441,23 +453,24 @@ namespace Hantek {
441 453 samplerateId = SAMPLERATE_50MS;
442 454  
443 455 // The values that are understood by the oscilloscope
  456 + /// \todo Check large buffer values, seem to be crap
444 457 static const unsigned char valueFastSmall[5] = {0, 1, 2, 3, 4};
445 458 static const unsigned char valueFastLarge[5] = {0, 0, 0, 2, 3};
446   - static const unsigned short int valueSlowSmall[13] = {0xffff, 0xfffc, 0xfff7, 0xffe8, 0xffce, 0xff9c, 0xff07, 0xfe0d, 0xfc19, 0xf63d, 0xec79, 0xd8f1, 0xffed};
447   - static const unsigned short int valueSlowLarge[13] = {0xffff, 0x0000, 0xfffc, 0xfff7, 0xffe8, 0xffce, 0xff9d, 0xff07, 0xfe0d, 0xfc19, 0xf63d, 0xec79, 0xffed}; /// \todo Check those values
  459 + static const unsigned short int valueSlowSmall[13] = {0xfffe, 0xfffc, 0xfff7, 0xffe8, 0xffce, 0xff9c, 0xff07, 0xfe0d, 0xfc19, 0xf63d, 0xec79, 0xd8f1, 0xffed};
  460 + static const unsigned short int valueSlowLarge[13] = {0xffff, 0x0000, 0xfffc, 0xfff7, 0xffe8, 0xffce, 0xff9d, 0xff07, 0xfe0d, 0xfc19, 0xf63d, 0xec79, 0xffed};
448 461  
449 462 // SetTriggerAndSamplerate bulk command for samplerate
450 463 CommandSetTriggerAndSamplerate *commandSetTriggerAndSamplerate = (CommandSetTriggerAndSamplerate *) this->command[COMMAND_SETTRIGGERANDSAMPLERATE];
451 464  
452 465 // Set SamplerateFast bits for high sampling rates
453 466 if(samplerateId <= SAMPLERATE_5MS)
454   - commandSetTriggerAndSamplerate->setSamplerateFast(this->bufferSize == BUFFER_SMALL ? valueFastSmall[samplerateId] : valueFastLarge[samplerateId]);
  467 + commandSetTriggerAndSamplerate->setSamplerateFast(this->bufferSize == BUFFER_SMALL ? valueFastSmall[samplerateId - SAMPLERATE_100MS] : valueFastLarge[samplerateId - SAMPLERATE_100MS]);
455 468 else
456 469 commandSetTriggerAndSamplerate->setSamplerateFast(4);
457 470  
458 471 // Set normal Samplerate value for lower sampling rates
459   - if(samplerateId >= SAMPLERATE_2_5MS)
460   - commandSetTriggerAndSamplerate->setSamplerate(this->bufferSize == BUFFER_SMALL ? valueSlowSmall[samplerateId - SAMPLERATE_2_5MS] : valueSlowLarge[samplerateId - SAMPLERATE_2_5MS]);
  472 + if(samplerateId >= SAMPLERATE_10MS)
  473 + commandSetTriggerAndSamplerate->setSamplerate(this->bufferSize == BUFFER_SMALL ? valueSlowSmall[samplerateId - SAMPLERATE_10MS] : valueSlowLarge[samplerateId - SAMPLERATE_10MS]);
461 474 else
462 475 commandSetTriggerAndSamplerate->setSamplerate(0x0000);
463 476  
... ... @@ -467,6 +480,9 @@ namespace Hantek {
467 480 this->commandPending[COMMAND_SETTRIGGERANDSAMPLERATE] = true;
468 481  
469 482 this->samplerate = (Samplerate) samplerateId;
  483 +
  484 + this->updateBufferSize(this->bufferSize);
  485 + this->setTriggerSlope(this->triggerSlope);
470 486 return this->samplerateSteps[samplerateId];
471 487 }
472 488  
... ... @@ -648,7 +664,7 @@ namespace Hantek {
648 664 return -1;
649 665  
650 666 // SetTriggerAndSamplerate bulk command for trigger position
651   - ((CommandSetTriggerAndSamplerate *) this->command[COMMAND_SETTRIGGERANDSAMPLERATE])->setTriggerSlope(slope);
  667 + ((CommandSetTriggerAndSamplerate *) this->command[COMMAND_SETTRIGGERANDSAMPLERATE])->setTriggerSlope((this->bufferSize != BUFFER_SMALL || this->samplerate > SAMPLERATE_10MS || (SAMPLERATE_10MS - this->samplerate) % 2) ? slope : Dso::SLOPE_NEGATIVE - slope);
652 668 this->commandPending[COMMAND_SETTRIGGERANDSAMPLERATE] = true;
653 669  
654 670 return 0;
... ... @@ -667,6 +683,7 @@ namespace Hantek {
667 683 ((CommandSetTriggerAndSamplerate *) this->command[COMMAND_SETTRIGGERANDSAMPLERATE])->setTriggerPosition(positionValue);
668 684 this->commandPending[COMMAND_SETTRIGGERANDSAMPLERATE] = true;
669 685  
  686 + this->triggerPosition = position;
670 687 return (double) (positionValue - positionStart) / this->samplerateSteps[this->samplerate];
671 688 }
672 689 }
... ...
openhantek/src/hantek/control.h
... ... @@ -70,6 +70,7 @@ namespace Hantek {
70 70 unsigned int calculateTriggerPoint(unsigned int value);
71 71 int getCaptureState();
72 72 int getSamples(bool process);
  73 + unsigned long int updateBufferSize(unsigned long int size);
73 74  
74 75 Device *device; ///< The USB device for the oscilloscope
75 76  
... ... @@ -88,9 +89,11 @@ namespace Hantek {
88 89 double offset[HANTEK_CHANNELS]; ///< The current screen offset for each channel
89 90 double offsetReal[HANTEK_CHANNELS]; ///< The real offset for each channel (Due to quantization)
90 91 double triggerLevel[HANTEK_CHANNELS]; ///< The trigger level for each channel in V
  92 + double triggerPosition; ///< The current pretrigger position
91 93 unsigned int bufferSize; ///< The buffer size in samples
92 94 unsigned int triggerPoint; ///< The trigger point value
93 95 Dso::TriggerMode triggerMode; ///< The trigger mode
  96 + Dso::Slope triggerSlope; ///< The trigger slope
94 97 bool triggerSpecial; ///< true, if the trigger source is special
95 98 unsigned int triggerSource; ///< The trigger source
96 99  
... ... @@ -105,7 +108,7 @@ namespace Hantek {
105 108  
106 109 public slots:
107 110 unsigned long int setSamplerate(unsigned long int samplerate);
108   - double setBufferSize(unsigned int size);
  111 + unsigned long int setBufferSize(unsigned long int size);
109 112  
110 113 int setChannelUsed(unsigned int channel, bool used);
111 114 int setCoupling(unsigned int channel, Dso::Coupling coupling);
... ...
openhantek/src/hantek/types.h
... ... @@ -137,6 +137,7 @@ namespace Hantek {
137 137 /// <td>...</td>
138 138 /// </tr>
139 139 /// </table>
  140 + /// Because of the 9 bit data model, the DSO-5200 transmits an additional MSB for each sample afterwards.
140 141 COMMAND_GETDATA,
141 142  
142 143 /// This command checks the capture state:
... ... @@ -146,7 +147,7 @@ namespace Hantek {
146 147 /// <td>0x00</td>
147 148 /// </tr>
148 149 /// </table>
149   - /// The oscilloscope returns it's capture state and the trigger point (Not sure about this, looks like 248 16-bit words with nearly constant values):
  150 + /// The oscilloscope returns it's capture state and the trigger point. Not sure about this, looks like 248 16-bit words with nearly constant values. These can be converted to the start address of the data in the buffer (See Hantek::Control::calculateTriggerPoint):
150 151 /// <table>
151 152 /// <tr>
152 153 /// <td>#CaptureState</td>
... ... @@ -214,10 +215,10 @@ namespace Hantek {
214 215 /// \enum ControlCode hantek/types.h
215 216 /// \brief All supported control commands.
216 217 enum ControlCode {
217   - /// This control read/write command gives access to a #ControlValue.
218   - CONTROL_VALUE = 0xA2,
  218 + /// The 0xa2 control read/write command gives access to a #ControlValue.
  219 + CONTROL_VALUE = 0xa2,
219 220  
220   - /// This control read command gets the speed level of the USB connection:
  221 + /// The 0xb2 control read command gets the speed level of the USB connection:
221 222 /// <table>
222 223 /// <tr>
223 224 /// <td>#ConnectionSpeed</td>
... ... @@ -232,9 +233,9 @@ namespace Hantek {
232 233 /// <td>0x00</td>
233 234 /// </tr>
234 235 /// </table>
235   - CONTROL_GETSPEED = 0xB2,
  236 + CONTROL_GETSPEED = 0xb2,
236 237  
237   - /// This control write command is sent before any bulk command:
  238 + /// The 0xb3 control write command is sent before any bulk command:
238 239 /// <table>
239 240 /// <tr>
240 241 /// <td>0x0f</td>
... ... @@ -249,9 +250,9 @@ namespace Hantek {
249 250 /// <td>0x00</td>
250 251 /// </tr>
251 252 /// </table>
252   - CONTROL_BEGINCOMMAND = 0xB3,
  253 + CONTROL_BEGINCOMMAND = 0xb3,
253 254  
254   - /// This control write command sets the channel offsets:
  255 + /// The 0xb4 control write command sets the channel offsets:
255 256 /// <table>
256 257 /// <tr>
257 258 /// <td>Ch1Offset[1] | 0x20</td>
... ... @@ -273,9 +274,9 @@ namespace Hantek {
273 274 /// <td>0x00</td>
274 275 /// </tr>
275 276 /// </table>
276   - CONTROL_SETOFFSET = 0xB4,
  277 + CONTROL_SETOFFSET = 0xb4,
277 278  
278   - /// This control write command sets the internal relays:
  279 + /// The 0xb5 control write command sets the internal relays:
279 280 /// <table>
280 281 /// <tr>
281 282 /// <td>0x00</td>
... ... @@ -297,7 +298,7 @@ namespace Hantek {
297 298 /// <td>0x00</td>
298 299 /// </tr>
299 300 /// </table>
300   - CONTROL_SETRELAYS = 0xB5
  301 + CONTROL_SETRELAYS = 0xb5
301 302 };
302 303  
303 304 //////////////////////////////////////////////////////////////////////////////
... ... @@ -446,7 +447,7 @@ namespace Hantek {
446 447 /// \brief Trigger and samplerate bits (Byte 1).
447 448 struct Tsr1Bits {
448 449 unsigned char triggerSource:2; ///< The trigger source, see Hantek::TriggerSource
449   - unsigned char sampleSize:3; ///< Buffer size, 1 = 10240 S, 2 = 32768 S
  450 + unsigned char sampleSize:3; ///< Buffer size, 0 = Roll, 1 = 10240 S, 2 = 32768 S
450 451 unsigned char samplerateFast:3; ///< samplerate id for fast sampling rates
451 452 };
452 453  
... ...
openhantek/src/helper.cpp
... ... @@ -44,33 +44,33 @@ namespace Helper {
44 44 QString libUsbErrorString(int error) {
45 45 switch(error) {
46 46 case LIBUSB_SUCCESS:
47   - return "Success (no error)";
  47 + return QApplication::tr("Success (no error)");
48 48 case LIBUSB_ERROR_IO:
49   - return "Input/output error";
  49 + return QApplication::tr("Input/output error");
50 50 case LIBUSB_ERROR_INVALID_PARAM:
51   - return "Invalid parameter";
  51 + return QApplication::tr("Invalid parameter");
52 52 case LIBUSB_ERROR_ACCESS:
53   - return "Access denied (insufficient permissions)";
  53 + return QApplication::tr("Access denied (insufficient permissions)");
54 54 case LIBUSB_ERROR_NO_DEVICE:
55   - return "No such device (it may have been disconnected)";
  55 + return QApplication::tr("No such device (it may have been disconnected)");
56 56 case LIBUSB_ERROR_NOT_FOUND:
57   - return "Entity not found";
  57 + return QApplication::tr("Entity not found");
58 58 case LIBUSB_ERROR_BUSY:
59   - return "Resource busy";
  59 + return QApplication::tr("Resource busy");
60 60 case LIBUSB_ERROR_TIMEOUT:
61   - return "Operation timed out";
  61 + return QApplication::tr("Operation timed out");
62 62 case LIBUSB_ERROR_OVERFLOW:
63   - return "Overflow";
  63 + return QApplication::tr("Overflow");
64 64 case LIBUSB_ERROR_PIPE:
65   - return "Pipe error";
  65 + return QApplication::tr("Pipe error");
66 66 case LIBUSB_ERROR_INTERRUPTED:
67   - return "System call interrupted (perhaps due to signal)";
  67 + return QApplication::tr("System call interrupted (perhaps due to signal)");
68 68 case LIBUSB_ERROR_NO_MEM:
69   - return "Insufficient memory";
  69 + return QApplication::tr("Insufficient memory");
70 70 case LIBUSB_ERROR_NOT_SUPPORTED:
71   - return "Operation not supported or unimplemented on this platform";
  71 + return QApplication::tr("Operation not supported or unimplemented on this platform");
72 72 default:
73   - return "Other error";
  73 + return QApplication::tr("Other error");
74 74 }
75 75 }
76 76  
... ...
openhantek/src/openhantek.cpp
... ... @@ -139,7 +139,7 @@ OpenHantekMainWindow::OpenHantekMainWindow(QWidget *parent, Qt::WindowFlags flag
139 139 this->dsoControl->setBufferSize(this->settings->scope.horizontal.samples);
140 140 this->updateTimebase();
141 141 this->dsoControl->setTriggerMode(this->settings->scope.trigger.mode);
142   - this->dsoControl->setTriggerPosition(this->settings->scope.trigger.position);
  142 + this->dsoControl->setTriggerPosition(this->settings->scope.trigger.position * this->settings->scope.horizontal.timebase * DIVS_TIME);
143 143 this->dsoControl->setTriggerSlope(this->settings->scope.trigger.slope);
144 144 this->dsoControl->setTriggerSource(this->settings->scope.trigger.special, this->settings->scope.trigger.source);
145 145  
... ... @@ -432,11 +432,11 @@ void OpenHantekMainWindow::readSettings(const QString &amp;fileName) {
432 432 if(settingsLoader->contains("digitalPhosphor"))
433 433 this->settings->view.digitalPhosphor = settingsLoader->value("digitalPhosphor").toBool();
434 434 if(settingsLoader->contains("interpolation"))
435   - this->settings->view.interpolation = (GlInterpolationMode) settingsLoader->value("interpolation").toInt();
  435 + this->settings->view.interpolation = (Dso::InterpolationMode) settingsLoader->value("interpolation").toInt();
436 436 if(settingsLoader->contains("screenColorImages"))
437   - this->settings->view.screenColorImages = (GlInterpolationMode) settingsLoader->value("screenColorImages").toBool();
  437 + this->settings->view.screenColorImages = (Dso::InterpolationMode) settingsLoader->value("screenColorImages").toBool();
438 438 if(settingsLoader->contains("zoom"))
439   - this->settings->view.zoom = (GlInterpolationMode) settingsLoader->value("zoom").toBool();
  439 + this->settings->view.zoom = (Dso::InterpolationMode) settingsLoader->value("zoom").toBool();
440 440 settingsLoader->endGroup();
441 441  
442 442 delete settingsLoader;
... ...
openhantek/src/settings.cpp
... ... @@ -27,7 +27,7 @@
27 27  
28 28 #include "settings.h"
29 29  
30   -#include "constants.h"
  30 +#include "dso.h"
31 31 #include "dsowidget.h"
32 32  
33 33  
... ... @@ -81,7 +81,7 @@ DsoSettings::DsoSettings() {
81 81 this->view.antialiasing = true;
82 82 this->view.digitalPhosphor = false;
83 83 this->view.digitalPhosphorDepth = 8;
84   - this->view.interpolation = INTERPOLATION_LINEAR;
  84 + this->view.interpolation = Dso::INTERPOLATION_LINEAR;
85 85 this->view.screenColorImages = false;
86 86 this->view.zoom = false;
87 87 }
... ...
openhantek/src/settings.h
... ... @@ -32,7 +32,7 @@
32 32 #include <QString>
33 33  
34 34  
35   -#include "constants.h"
  35 +#include "dso.h"
36 36  
37 37  
38 38 ////////////////////////////////////////////////////////////////////////////////
... ... @@ -133,7 +133,7 @@ struct DsoSettingsView {
133 133 bool antialiasing; ///< Antialiasing for the graphs
134 134 bool digitalPhosphor; ///< true slowly fades out the previous graphs
135 135 int digitalPhosphorDepth; ///< Number of channels shown at one time
136   - GlInterpolationMode interpolation; ///< Interpolation mode for the graph
  136 + Dso::InterpolationMode interpolation; ///< Interpolation mode for the graph
137 137 bool screenColorImages; ///< true exports images with screen colors
138 138 bool zoom; ///< true if the magnified scope is enabled
139 139 };
... ...