Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Openhantek2 #300

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
36 changes: 30 additions & 6 deletions docs/adddevice.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ We only accept new devices whoms firmware is hantek protocol compatible.
Codewise you will only need to touch files within `openhantek/src/hantekdso`.

## Firmware and usb access
The firmware goes to `openhantek/res/firmware` in the hex format. Please keep to the filename
The firmware goes to `openhantek/res/firmware` in intel hex format. Please keep to the filename
convention devicename-firmware.hex and devicename-loader.hex.
The `openhantek/res/firmwares.qrc` should list the new files.
The firmware/60-hantek.rules file needs the usb vendor/device id to add access permissions.

The firmware/60-hantek.rules file needs the usb vendor/device id to add access permissions for linux users.
MacOS users do not have access restrictions. On Windows there need to be a driver installed that
also manages the usb access.

## The hantek protocol
The hantek protocol itself is encoded in the `src/hantekprotocol` files.
Expand All @@ -24,7 +27,7 @@ You will only need to touch files within `openhantek/src/hantekdso/models`.
struct ModelDSO2090 : public DSOModel {
static const int ID = 0x2090; // Freely chooseable but unique id
ModelDSO2090();
void applyRequirements(HantekDsoControl* dsoControl) const override;
void applyRequirements(DsoCommandQueue* commandQueue) const override;
};
```

Expand All @@ -37,7 +40,7 @@ DSOModel(int ID, long vendorID, long productID, long vendorIDnoFirmware, long pr
```

* You need to find out the usb vendor id and product id for your digital oscilloscope after it has received
the firmware (for ``long vendorID``, ``long productID``) and before it has a valid firmware
the firmware (for ``long vendorID``, ``long productID``) and also before it has a valid firmware
(for ``long vendorIDnoFirmware``, ``long productIDnoFirmware``).
* The firmware token is just the devicename part of the firmware
(remember that we used `devicename-firmware.hex` and `devicename-loader.hex`).
Expand All @@ -56,7 +59,7 @@ DSOModel(int ID, long vendorID, long productID, long vendorIDnoFirmware, long pr
specification.samplerate.multi.recordLengths = {UINT_MAX, 20480, 65536};
```

4. The actual commands that are send, need to be defined as well, for instance:
4. The command prototypes that are used need to be defined, for instance:

``` c++
specification.command.control.setOffset = CONTROL_SETOFFSET;
Expand All @@ -69,7 +72,28 @@ DSOModel(int ID, long vendorID, long productID, long vendorIDnoFirmware, long pr
specification.command.bulk.setPretrigger = BulkCode::SETTRIGGERANDSAMPLERATE;
```

5. Add an instance of your class to the cpp file. The `DSOModel` constructor will register
5. You need to register the actual commands to the DsoCommandQueue object like this:

``` c++
void ModelDSO2150::applyRequirements(DsoCommandQueue *commandQueue) const {
commandQueue->addCommand(new BulkForceTrigger(), false);
commandQueue->addCommand(new BulkCaptureStart(), false);
commandQueue->addCommand(new BulkTriggerEnabled(), false);
commandQueue->addCommand(new BulkGetData(), false);
commandQueue->addCommand(new BulkGetCaptureState(), false);
commandQueue->addCommand(new BulkSetGain(), false);

commandQueue->addCommand(new BulkSetTriggerAndSamplerate(), false);
commandQueue->addCommand(new ControlSetOffset(), false);
commandQueue->addCommand(new ControlSetRelays(), false);
}
```

If you define a command prototype in (4) but do not register the actual command in (5), the application
will crash. Guaranteed!
Always create new heap objects for the command queue. The queue will clean up after itself.

6. Add an object instance of your class to the cpp file as last line. The `DSOModel` constructor will register
your new model automatically to the ModelRegistry:

```
Expand Down
2 changes: 1 addition & 1 deletion docs/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ layout: default
---
### [Linux](#linux)
For debian (stretch and newer), Ubuntu 17.04+ and Mint 17+ and other deb based distributions install named requirements like this:
> apt install g++ cmake qttools5-dev qttools5-dev-tools libfftw3-dev binutils-dev libusb-1.0-0-dev libqt5opengl5-dev mesa-common-dev libgl1-mesa-dev libgles2-mesa-dev
> apt install g++ cmake qttools5-dev qttools5-dev-tools libfftw3-dev binutils-dev libusb-1.0-0-dev qt3d5-dev qt3d-assimpsceneio-plugin qt3d-gltfsceneio-plugin

For rpm based distributions (Fedora 21+, OpenSuse) use this command:
> dnf install cmake gcc-c++ qt5-qtbase-gui qt5-qttools-devel qt5-qttranslations fftw-devel binutils-devel libusb-devel mesa-libGL-devel mesa-libGLES-devel
Expand Down
49 changes: 36 additions & 13 deletions openhantek/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,37 +1,60 @@
project(OpenHantek CXX)

find_package(Qt5Widgets REQUIRED)
find_package(Qt5PrintSupport REQUIRED)
find_package(Qt5OpenGL REQUIRED)
find_package(OpenGL)
find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets PrintSupport 3DCore 3DExtras 3DRender 3DInput)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)

if (Qt5Widgets_VERSION VERSION_LESS 5.4.0)
message(FATAL_ERROR "Minimum supported Qt5 version is 5.4.0!")
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

if (Qt5Widgets_VERSION VERSION_LESS 5.7.0)
message(FATAL_ERROR "Minimum supported Qt5 version is 5.7.0!")
endif()

# include directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
include_directories(src/ src/hantekdso src/widgets src/docks src/configdialog)
include_directories(src/ src/hantekdso src/settings) # src/widgets src/scopeview

# collect sources and other files
file(GLOB_RECURSE SRC "src/*.cpp")
file(GLOB_RECURSE HEADERS "src/*.h")
file(GLOB_RECURSE SRC_CORE
"src/hantekdso/*.cpp" "src/hantekprotocol/*.cpp" "src/hantekprotocol/*.cpp" "src/usb/*.cpp" "src/utils/*.cpp"
"src/hantekdso/*.h" "src/hantekprotocol/*.h" "src/hantekprotocol/*.h" "src/usb/*.h" "src/utils/*.h")
file(GLOB_RECURSE SRC_POST "src/post/*.cpp" "src/post/*.h")
file(GLOB_RECURSE SRC_SETTINGS "src/settings/*.cpp" "src/settings/*.h")
file(GLOB_RECURSE SRC_EXPORT "src/exporting/*.cpp" "src/exporting/*.h")
file(GLOB_RECURSE SRC_SCOPEVIEW "src/scopeview/*.cpp" "src/scopeview/*.h")
file(GLOB SRC_UI "src/main.cpp"
"src/widgets/*.cpp" "src/widgets/*.h"
"src/mainwindow.cpp" "src/mainwindow.h"
"src/configdialog/*.cpp" "src/configdialog/*.h"
"src/docks/*.cpp" "src/docks/*.h"
"src/iconfont/*.cpp" "src/iconfont/*.h"
"src/selectdevice/*.cpp" "src/selectdevice/*.h")
set(SRC ${SRC_CORE} ${SRC_POST} ${SRC_SETTINGS} ${SRC_EXPORT} ${SRC_SCOPEVIEW} ${SRC_UI})

file(GLOB_RECURSE UI "src/*.ui")
file(GLOB_RECURSE QRC "res/*.qrc")

add_custom_target(format SOURCES ".clang-format"
COMMAND "clang-format" "-style=file" "-i" "-sort-includes" ${SRC} ${HEADERS})
COMMAND "clang-format" "-style=file" "-i" "-sort-includes" ${SRC})

add_subdirectory(translations)

add_definitions(-DVERSION="${CPACK_PACKAGE_VERSION}")
add_definitions(-DVERSION="${CPACK_PACKAGE_VERSION}" -Wall)

# make executable
add_executable(${PROJECT_NAME} ${SRC} ${HEADERS} ${UI} ${QRC} ${TRANSLATION_BIN_FILES} ${TRANSLATION_QRC})
target_link_libraries(${PROJECT_NAME} Qt5::Widgets Qt5::PrintSupport Qt5::OpenGL ${OPENGL_LIBRARIES} )
add_executable(${PROJECT_NAME} ${SRC} ${UI} ${QRC} ${TRANSLATION_BIN_FILES} ${TRANSLATION_QRC})
target_link_libraries(${PROJECT_NAME}
Qt5::Core
Qt5::Gui
Qt5::Widgets
Qt5::3DCore
Qt5::3DExtras
Qt5::3DRender
Qt5::3DInput
Qt5::PrintSupport)
target_compile_features(${PROJECT_NAME} PRIVATE cxx_range_for)
if(MSVC)
target_compile_options(${PROJECT_NAME} PRIVATE "/W4" "/wd4251" "/wd4127" "/wd4275" "/wd4200" "/nologo" "/J" "/Zi")
Expand Down
14 changes: 7 additions & 7 deletions openhantek/src/configdialog/DsoConfigAnalysisPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#include "DsoConfigAnalysisPage.h"

DsoConfigAnalysisPage::DsoConfigAnalysisPage(DsoSettings *settings, QWidget *parent)
DsoConfigAnalysisPage::DsoConfigAnalysisPage(Settings::DsoSettings *settings, QWidget *parent)
: QWidget(parent), settings(settings) {
// Initialize lists for comboboxes
QStringList windowFunctionStrings;
Expand All @@ -15,14 +15,14 @@ DsoConfigAnalysisPage::DsoConfigAnalysisPage(DsoSettings *settings, QWidget *par
windowFunctionLabel = new QLabel(tr("Window function"));
windowFunctionComboBox = new QComboBox();
windowFunctionComboBox->addItems(windowFunctionStrings);
windowFunctionComboBox->setCurrentIndex((int)settings->post.spectrumWindow);
windowFunctionComboBox->setCurrentIndex((int)settings->post.spectrumWindow());

referenceLevelLabel = new QLabel(tr("Reference level"));
referenceLevelSpinBox = new QDoubleSpinBox();
referenceLevelSpinBox->setDecimals(1);
referenceLevelSpinBox->setMinimum(-40.0);
referenceLevelSpinBox->setMaximum(100.0);
referenceLevelSpinBox->setValue(settings->post.spectrumReference);
referenceLevelSpinBox->setValue(settings->post.spectrumReference());
referenceLevelUnitLabel = new QLabel(tr("dBm"));
referenceLevelLayout = new QHBoxLayout();
referenceLevelLayout->addWidget(referenceLevelSpinBox);
Expand All @@ -33,7 +33,7 @@ DsoConfigAnalysisPage::DsoConfigAnalysisPage(DsoSettings *settings, QWidget *par
minimumMagnitudeSpinBox->setDecimals(1);
minimumMagnitudeSpinBox->setMinimum(-40.0);
minimumMagnitudeSpinBox->setMaximum(100.0);
minimumMagnitudeSpinBox->setValue(settings->post.spectrumLimit);
minimumMagnitudeSpinBox->setValue(settings->post.spectrumLimit());
minimumMagnitudeUnitLabel = new QLabel(tr("dBm"));
minimumMagnitudeLayout = new QHBoxLayout();
minimumMagnitudeLayout->addWidget(minimumMagnitudeSpinBox);
Expand All @@ -59,7 +59,7 @@ DsoConfigAnalysisPage::DsoConfigAnalysisPage(DsoSettings *settings, QWidget *par

/// \brief Saves the new settings.
void DsoConfigAnalysisPage::saveSettings() {
settings->post.spectrumWindow = (Dso::WindowFunction)windowFunctionComboBox->currentIndex();
settings->post.spectrumReference = referenceLevelSpinBox->value();
settings->post.spectrumLimit = minimumMagnitudeSpinBox->value();
settings->post.m_spectrumWindow = (PostProcessingE::WindowFunction)windowFunctionComboBox->currentIndex();
settings->post.m_spectrumReference = referenceLevelSpinBox->value();
settings->post.m_spectrumLimit = minimumMagnitudeSpinBox->value();
}
6 changes: 2 additions & 4 deletions openhantek/src/configdialog/DsoConfigAnalysisPage.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,18 @@
#include <QSpinBox>
#include <QVBoxLayout>

////////////////////////////////////////////////////////////////////////////////
/// \class DsoConfigAnalysisPage configpages.h
/// \brief Config page for the data analysis.
class DsoConfigAnalysisPage : public QWidget {
Q_OBJECT

public:
DsoConfigAnalysisPage(DsoSettings *settings, QWidget *parent = 0);
DsoConfigAnalysisPage(Settings::DsoSettings *settings, QWidget *parent = 0);

public slots:
void saveSettings();

private:
DsoSettings *settings;
Settings::DsoSettings *settings;

QVBoxLayout *mainLayout;

Expand Down
110 changes: 64 additions & 46 deletions openhantek/src/configdialog/DsoConfigColorsPage.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
// SPDX-License-Identifier: GPL-2.0+

#include "DsoConfigColorsPage.h"
#include "widgets/colorbox.h"

DsoConfigColorsPage::DsoConfigColorsPage(DsoSettings *settings, QWidget *parent) : QWidget(parent), settings(settings) {
DsoConfigColorsPage::DsoConfigColorsPage(Settings::DsoSettings *settings, QWidget *parent)
: QWidget(parent), settings(settings) {
// Initialize elements
DsoSettingsView &colorSettings = settings->view;
Settings::View &colorSettings = settings->view;
enum { COL_LABEL = 0, COL_SCR_CHANNEL, COL_SCR_SPECTRUM, COL_PRT_CHANNEL, COL_PRT_SPECTRUM };

QVBoxLayout *mainLayout;

QGroupBox *colorsGroup;
QGridLayout *colorsLayout;

QLabel *screenColorsLabel, *printColorsLabel;
QLabel *axesLabel, *backgroundLabel, *borderLabel, *gridLabel, *markersLabel, *textLabel;
QLabel *graphLabel;
QLabel *screenChannelLabel, *screenSpectrumLabel, *printChannelLabel, *printSpectrumLabel;

// Plot Area
graphLabel = new QLabel(tr("<hr width=\"100%\"/>")); // 4*80
graphLabel->setAlignment(Qt::AlignRight);
Expand All @@ -18,28 +30,28 @@ DsoConfigColorsPage::DsoConfigColorsPage(DsoSettings *settings, QWidget *parent)
printColorsLabel->setAlignment(Qt::AlignHCenter);

axesLabel = new QLabel(tr("Axes"));
axesColorBox = new ColorBox(colorSettings.screen.axes);
printAxesColorBox = new ColorBox(colorSettings.print.axes);
axesColorBox = new ColorBox(colorSettings.screen.axes());
printAxesColorBox = new ColorBox(colorSettings.print.axes());

backgroundLabel = new QLabel(tr("Background"));
backgroundColorBox = new ColorBox(colorSettings.screen.background);
printBackgroundColorBox = new ColorBox(colorSettings.print.background);
backgroundColorBox = new ColorBox(colorSettings.screen.background());
printBackgroundColorBox = new ColorBox(colorSettings.print.background());

borderLabel = new QLabel(tr("Border"));
borderColorBox = new ColorBox(colorSettings.screen.border);
printBorderColorBox = new ColorBox(colorSettings.print.border);
borderColorBox = new ColorBox(colorSettings.screen.border());
printBorderColorBox = new ColorBox(colorSettings.print.border());

gridLabel = new QLabel(tr("Grid"));
gridColorBox = new ColorBox(colorSettings.screen.grid);
printGridColorBox = new ColorBox(colorSettings.print.grid);
gridColorBox = new ColorBox(colorSettings.screen.grid());
printGridColorBox = new ColorBox(colorSettings.print.grid());

markersLabel = new QLabel(tr("Markers"));
markersColorBox = new ColorBox(colorSettings.screen.markers);
printMarkersColorBox = new ColorBox(colorSettings.print.markers);
markersColorBox = new ColorBox(colorSettings.screen.markers());
printMarkersColorBox = new ColorBox(colorSettings.print.markers());

textLabel = new QLabel(tr("Text"));
textColorBox = new ColorBox(colorSettings.screen.text);
printTextColorBox = new ColorBox(colorSettings.print.text);
textColorBox = new ColorBox(colorSettings.screen.text());
printTextColorBox = new ColorBox(colorSettings.print.text());

// Graph category
screenChannelLabel = new QLabel(tr("Channel"));
Expand All @@ -51,14 +63,6 @@ DsoConfigColorsPage::DsoConfigColorsPage(DsoSettings *settings, QWidget *parent)
printSpectrumLabel = new QLabel(tr("Spectrum"));
printSpectrumLabel->setAlignment(Qt::AlignHCenter);

for (ChannelID channel = 0; channel < settings->scope.voltage.size(); ++channel) {
colorLabel.push_back(new QLabel(settings->scope.voltage[channel].name));
screenChannelColorBox.push_back(new ColorBox(colorSettings.screen.voltage[channel]));
screenSpectrumColorBox.push_back(new ColorBox(colorSettings.screen.spectrum[channel]));
printChannelColorBox.push_back(new ColorBox(colorSettings.print.voltage[channel]));
printSpectrumColorBox.push_back(new ColorBox(colorSettings.print.spectrum[channel]));
}

// Plot Area Layout
colorsLayout = new QGridLayout();
colorsLayout->setColumnStretch(COL_LABEL, 1);
Expand Down Expand Up @@ -106,12 +110,21 @@ DsoConfigColorsPage::DsoConfigColorsPage(DsoSettings *settings, QWidget *parent)
colorsLayout->addWidget(printSpectrumLabel, row, COL_PRT_SPECTRUM);
++row;

for (ChannelID channel = 0; channel < settings->scope.voltage.size(); ++channel, ++row) {
colorsLayout->addWidget(colorLabel[channel], row, COL_LABEL);
colorsLayout->addWidget(screenChannelColorBox[channel], row, COL_SCR_CHANNEL);
colorsLayout->addWidget(screenSpectrumColorBox[channel], row, COL_SCR_SPECTRUM);
colorsLayout->addWidget(printChannelColorBox[channel], row, COL_PRT_CHANNEL);
colorsLayout->addWidget(printSpectrumColorBox[channel], row, COL_PRT_SPECTRUM);
for (auto *channelSettings : settings->scope) {
ChannelColors *cc = new ChannelColors(this);
QLabel *colorLabel = new QLabel(channelSettings->name());
cc->screenChannelColorBox = new ColorBox(colorSettings.screen.voltage(channelSettings->channelID()));
cc->screenSpectrumColorBox = new ColorBox(colorSettings.screen.spectrum(channelSettings->channelID()));
cc->printChannelColorBox = new ColorBox(colorSettings.print.voltage(channelSettings->channelID()));
cc->printSpectrumColorBox = new ColorBox(colorSettings.print.spectrum(channelSettings->channelID()));
m_channelColorMap.insert(std::make_pair(channelSettings->channelID(), cc));

colorsLayout->addWidget(colorLabel, row, COL_LABEL);
colorsLayout->addWidget(cc->screenChannelColorBox, row, COL_SCR_CHANNEL);
colorsLayout->addWidget(cc->screenSpectrumColorBox, row, COL_SCR_SPECTRUM);
colorsLayout->addWidget(cc->printChannelColorBox, row, COL_PRT_CHANNEL);
colorsLayout->addWidget(cc->printSpectrumColorBox, row, COL_PRT_SPECTRUM);
++row;
}

colorsGroup = new QGroupBox(tr("Screen and Print Colors"));
Expand All @@ -127,29 +140,34 @@ DsoConfigColorsPage::DsoConfigColorsPage(DsoSettings *settings, QWidget *parent)

/// \brief Saves the new settings.
void DsoConfigColorsPage::saveSettings() {
DsoSettingsView &colorSettings = settings->view;
Settings::View &colorSettings = settings->view;

// Screen category
colorSettings.screen.axes = axesColorBox->getColor();
colorSettings.screen.background = backgroundColorBox->getColor();
colorSettings.screen.border = borderColorBox->getColor();
colorSettings.screen.grid = gridColorBox->getColor();
colorSettings.screen.markers = markersColorBox->getColor();
colorSettings.screen.text = textColorBox->getColor();
colorSettings.screen._axes = axesColorBox->getColor();
colorSettings.screen._background = backgroundColorBox->getColor();
colorSettings.screen._border = borderColorBox->getColor();
colorSettings.screen._grid = gridColorBox->getColor();
colorSettings.screen._markers = markersColorBox->getColor();
colorSettings.screen._text = textColorBox->getColor();

// Print category
colorSettings.print.axes = printAxesColorBox->getColor();
colorSettings.print.background = printBackgroundColorBox->getColor();
colorSettings.print.border = printBorderColorBox->getColor();
colorSettings.print.grid = printGridColorBox->getColor();
colorSettings.print.markers = printMarkersColorBox->getColor();
colorSettings.print.text = printTextColorBox->getColor();
colorSettings.print._axes = printAxesColorBox->getColor();
colorSettings.print._background = printBackgroundColorBox->getColor();
colorSettings.print._border = printBorderColorBox->getColor();
colorSettings.print._grid = printGridColorBox->getColor();
colorSettings.print._markers = printMarkersColorBox->getColor();
colorSettings.print._text = printTextColorBox->getColor();

// Graph category
for (ChannelID channel = 0; channel < settings->scope.voltage.size(); ++channel) {
colorSettings.screen.voltage[channel] = screenChannelColorBox[channel]->getColor();
colorSettings.screen.spectrum[channel] = screenSpectrumColorBox[channel]->getColor();
colorSettings.print.voltage[channel] = printChannelColorBox[channel]->getColor();
colorSettings.print.spectrum[channel] = printSpectrumColorBox[channel]->getColor();
for (auto &c : m_channelColorMap) {
colorSettings.screen.setVoltage(c.first, c.second->screenChannelColorBox->getColor());
colorSettings.screen.setSpectrum(c.first, c.second->screenSpectrumColorBox->getColor());
colorSettings.print.setVoltage(c.first, c.second->printChannelColorBox->getColor());
colorSettings.print.setSpectrum(c.first, c.second->printSpectrumColorBox->getColor());
}

colorSettings.screen.observer()->update();
colorSettings.print.observer()->update();
}

ChannelColors::ChannelColors(QObject *parent) : QObject(parent) {}
Loading