diff --git a/openhantek/src/docks/TriggerDock.cpp b/openhantek/src/docks/TriggerDock.cpp index f5ebcac..4134158 100644 --- a/openhantek/src/docks/TriggerDock.cpp +++ b/openhantek/src/docks/TriggerDock.cpp @@ -16,21 +16,22 @@ #include "sispinbox.h" #include "utils/dsoStrings.h" #include "utils/printutils.h" +#include "hantekdso/controlspecification.h" -TriggerDock::TriggerDock(DsoSettings *settings, const std::vector &specialTriggers, QWidget *parent, +TriggerDock::TriggerDock(DsoSettingsScope *scope, const Dso::ControlSpecification* spec, QWidget *parent, Qt::WindowFlags flags) - : QDockWidget(tr("Trigger"), parent, flags), settings(settings) { + : QDockWidget(tr("Trigger"), parent, flags), scope(scope), spec(spec) { // Initialize lists for comboboxes - for (ChannelID channel = 0; channel < settings->deviceSpecification->channels; ++channel) + for (ChannelID channel = 0; channel < spec->channels; ++channel) this->sourceStandardStrings << tr("CH%1").arg(channel + 1); - for(const std::string& name: specialTriggers) - this->sourceSpecialStrings.append(QString::fromStdString(name)); + for(const Dso::SpecialTriggerChannel& specialTrigger: spec->specialTriggerChannels) + this->sourceSpecialStrings.append(QString::fromStdString(specialTrigger.name)); // Initialize elements this->modeLabel = new QLabel(tr("Mode")); this->modeComboBox = new QComboBox(); - for (Dso::TriggerMode mode: Dso::TriggerModeEnum) + for (Dso::TriggerMode mode: spec->triggerModes) this->modeComboBox->addItem(Dso::triggerModeString(mode)); this->slopeLabel = new QLabel(tr("Slope")); @@ -56,14 +57,19 @@ TriggerDock::TriggerDock(DsoSettings *settings, const std::vector & this->dockWidget = new QWidget(); SetupDockWidget(this, dockWidget, dockLayout); + // Set values + setMode(scope->trigger.mode); + setSlope(scope->trigger.slope); + setSource(scope->trigger.special, scope->trigger.source); + // Connect signals and slots - connect(this->modeComboBox, static_cast(&QComboBox::currentIndexChanged), [this](int index) { - this->settings->scope.trigger.mode = (Dso::TriggerMode)index; - emit modeChanged(this->settings->scope.trigger.mode); + connect(this->modeComboBox, static_cast(&QComboBox::currentIndexChanged), [this,spec](int index) { + this->scope->trigger.mode = spec->triggerModes[(unsigned)index]; + emit modeChanged(this->scope->trigger.mode); }); connect(this->slopeComboBox, static_cast(&QComboBox::currentIndexChanged), [this](int index) { - this->settings->scope.trigger.slope = (Dso::Slope)index; - emit slopeChanged(this->settings->scope.trigger.slope); + this->scope->trigger.slope = (Dso::Slope)index; + emit slopeChanged(this->scope->trigger.slope); }); connect(this->sourceComboBox, static_cast(&QComboBox::currentIndexChanged), [this](int index) { bool special = false; @@ -73,15 +79,10 @@ TriggerDock::TriggerDock(DsoSettings *settings, const std::vector & special = true; } - this->settings->scope.trigger.source = (unsigned) index; - this->settings->scope.trigger.special = special; + this->scope->trigger.source = (unsigned) index; + this->scope->trigger.special = special; emit sourceChanged(special, (unsigned)index); }); - - // Set values - this->setMode(settings->scope.trigger.mode); - this->setSlope(settings->scope.trigger.slope); - this->setSource(settings->scope.trigger.special, settings->scope.trigger.source); } /// \brief Don't close the dock, just hide it @@ -93,8 +94,9 @@ void TriggerDock::closeEvent(QCloseEvent *event) { } void TriggerDock::setMode(Dso::TriggerMode mode) { + int index = std::find(spec->triggerModes.begin(),spec->triggerModes.end(), mode) - spec->triggerModes.begin(); QSignalBlocker blocker(modeComboBox); - modeComboBox->setCurrentIndex((int)mode); + modeComboBox->setCurrentIndex(index); } void TriggerDock::setSlope(Dso::Slope slope) { diff --git a/openhantek/src/docks/TriggerDock.h b/openhantek/src/docks/TriggerDock.h index 44d151b..ab43c5b 100644 --- a/openhantek/src/docks/TriggerDock.h +++ b/openhantek/src/docks/TriggerDock.h @@ -4,14 +4,17 @@ #include #include +#include +#include +#include -#include "settings.h" - -class QLabel; -class QCheckBox; -class QComboBox; +#include "hantekdso/enums.h" class SiSpinBox; +class DsoSettingsScope; +namespace Dso { +struct ControlSpecification; +} /// \brief Dock window for the trigger settings. /// It contains the settings for the trigger mode, source and slope. @@ -21,10 +24,10 @@ class TriggerDock : public QDockWidget { public: /// \brief Initializes the trigger settings docking window. /// \param settings The target settings object. - /// \param specialTriggers The names of the special trigger sources. + /// \param spec /// \param parent The parent widget. /// \param flags Flags for the window manager. - TriggerDock(DsoSettings *settings, const std::vector& specialTriggers, QWidget *parent, Qt::WindowFlags flags = 0); + TriggerDock(DsoSettingsScope *scope, const Dso::ControlSpecification* spec, QWidget *parent, Qt::WindowFlags flags = 0); /// \brief Changes the trigger mode if the new mode is supported. /// \param mode The trigger mode. @@ -51,13 +54,11 @@ class TriggerDock : public QDockWidget { QComboBox *sourceComboBox; ///< Select the source for triggering QComboBox *slopeComboBox; ///< Select the slope that causes triggering - DsoSettings *settings; ///< The settings provided by the parent class + DsoSettingsScope *scope; ///< The settings provided by the parent class + const Dso::ControlSpecification* spec; - QStringList modeStrings; ///< Strings for the trigger modes QStringList sourceStandardStrings; ///< Strings for the standard trigger sources QStringList sourceSpecialStrings; ///< Strings for the special trigger sources - QStringList slopeStrings; ///< Strings for the trigger slopes - signals: void modeChanged(Dso::TriggerMode); ///< The trigger mode has been changed void sourceChanged(bool special, unsigned int id); ///< The trigger source has been changed diff --git a/openhantek/src/dsowidget.cpp b/openhantek/src/dsowidget.cpp index e36dce2..13c2445 100644 --- a/openhantek/src/dsowidget.cpp +++ b/openhantek/src/dsowidget.cpp @@ -441,7 +441,7 @@ void DsoWidget::doShowNewData() { exportNextFrame.reset(nullptr); } - bool triggered = generator->generateGraphs(data.get(), view->digitalPhosphorDraws(),scope,spec->channels); + bool triggered = generator->generateGraphs(data.get(), view->digitalPhosphorDraws(), scope, spec); QPalette triggerLabelPalette = palette(); triggerLabelPalette.setColor(QPalette::WindowText, Qt::black); diff --git a/openhantek/src/glgenerator.cpp b/openhantek/src/glgenerator.cpp index 59a6e65..feaa926 100644 --- a/openhantek/src/glgenerator.cpp +++ b/openhantek/src/glgenerator.cpp @@ -9,6 +9,7 @@ #include "analyse/dataanalyzerresult.h" #include "viewconstants.h" #include "hantekdso/softwaretrigger.h" +#include "hantekdso/controlspecification.h" static const SampleValues& useSamplesOf(Dso::ChannelMode mode, ChannelID channel, const DataAnalyzerResult *result, const DsoSettingsScope *scope) { static SampleValues emptyDefault; @@ -121,7 +122,7 @@ const std::vector &GlGenerator::grid(int a) const { return vaGrid[a]; } bool GlGenerator::isReady() const { return ready; } bool GlGenerator::generateGraphs(const DataAnalyzerResult *result, unsigned digitalPhosphorDepth, - const DsoSettingsScope *scope, unsigned physicalChannels) { + const DsoSettingsScope *scope, const Dso::ControlSpecification* spec) { // Handle all digital phosphor related list manipulations for (Dso::ChannelMode mode: Dso::ChannelModeEnum) { @@ -149,7 +150,9 @@ bool GlGenerator::generateGraphs(const DataAnalyzerResult *result, unsigned digi switch (scope->horizontal.format) { case Dso::GraphFormat::TY: - std::tie(preTrigSamples, postTrigSamples, swTriggerStart) = SoftwareTrigger::computeTY(result, scope, physicalChannels); + // check trigger point for software trigger + if (spec->isSoftwareTriggerDevice && scope->trigger.source < spec->channels) + std::tie(preTrigSamples, postTrigSamples, swTriggerStart) = SoftwareTrigger::compute(result, scope); triggered = postTrigSamples > preTrigSamples; // Add graphs for channels diff --git a/openhantek/src/glgenerator.h b/openhantek/src/glgenerator.h index 9eb5f7b..20fd022 100644 --- a/openhantek/src/glgenerator.h +++ b/openhantek/src/glgenerator.h @@ -12,6 +12,9 @@ struct DsoSettingsScope; class DataAnalyzerResult; +namespace Dso { +struct ControlSpecification; +} //////////////////////////////////////////////////////////////////////////////// /// \class GlGenerator @@ -26,7 +29,7 @@ class GlGenerator : public QObject { GlGenerator(); bool generateGraphs(const DataAnalyzerResult *result, unsigned digitalPhosphorDepth, const DsoSettingsScope *scope, - unsigned physicalChannels); + const Dso::ControlSpecification *spec); const std::vector &channel(Dso::ChannelMode mode, ChannelID channel, unsigned index) const; const std::vector &grid(int a) const; diff --git a/openhantek/src/hantekdso/controlsettings.h b/openhantek/src/hantekdso/controlsettings.h index 8744f3e..7d3e5c1 100644 --- a/openhantek/src/hantekdso/controlsettings.h +++ b/openhantek/src/hantekdso/controlsettings.h @@ -33,7 +33,7 @@ struct ControlSettingsTrigger { std::vector level; ///< The trigger level for each channel in V double position = 0.0; ///< The current pretrigger position unsigned int point = 0; ///< The trigger position in Hantek coding - Dso::TriggerMode mode = Dso::TriggerMode::NORMAL; ///< The trigger mode + Dso::TriggerMode mode = Dso::TriggerMode::HARDWARE_SOFTWARE; ///< The trigger mode Dso::Slope slope = Dso::Slope::Positive; ///< The trigger slope bool special = false; ///< true, if the trigger source is special unsigned int source = 0; ///< The trigger source diff --git a/openhantek/src/hantekdso/controlspecification.h b/openhantek/src/hantekdso/controlspecification.h index 12aef12..a8933d9 100644 --- a/openhantek/src/hantekdso/controlspecification.h +++ b/openhantek/src/hantekdso/controlspecification.h @@ -86,6 +86,7 @@ struct ControlSpecification { std::vector specialTriggerChannels; std::vector couplings = {Dso::Coupling::DC, Dso::Coupling::AC}; + std::vector triggerModes = {TriggerMode::HARDWARE_SOFTWARE, TriggerMode::WAIT_FORCE, TriggerMode::SINGLE}; bool isFixedSamplerateDevice = false; bool isSoftwareTriggerDevice = false; diff --git a/openhantek/src/hantekdso/enums.cpp b/openhantek/src/hantekdso/enums.cpp index 344fadd..d2e2a47 100644 --- a/openhantek/src/hantekdso/enums.cpp +++ b/openhantek/src/hantekdso/enums.cpp @@ -1,7 +1,7 @@ #include "enums.h" namespace Dso { - Enum TriggerModeEnum; + Enum TriggerModeEnum; Enum SlopeEnum; Enum GraphFormatEnum; Enum ChannelModeEnum; diff --git a/openhantek/src/hantekdso/enums.h b/openhantek/src/hantekdso/enums.h index d5856c6..4bae58a 100644 --- a/openhantek/src/hantekdso/enums.h +++ b/openhantek/src/hantekdso/enums.h @@ -6,7 +6,7 @@ namespace Dso { /// \enum ChannelMode /// \brief The channel display modes. enum class ChannelMode { - Voltage, ///< Standard voltage view + Voltage, ///< Standard voltage view Spectrum ///< Spectrum view }; constexpr int ChannelModes = 2; @@ -15,8 +15,8 @@ extern Enum GraphFormatEnum; @@ -32,12 +32,11 @@ enum class Coupling { /// \enum TriggerMode /// \brief The different triggering modes. enum class TriggerMode { - AUTO, ///< Automatic without trigger event - NORMAL, ///< Normal mode - SINGLE, ///< Stop after the first trigger event - SOFTWARE ///< Software trigger mode + HARDWARE_SOFTWARE, ///< Normal hardware trigger (or software trigger) mode + WAIT_FORCE, ///< Automatic without trigger event + SINGLE ///< Stop after the first trigger event }; -extern Enum TriggerModeEnum; +extern Enum TriggerModeEnum; /// \enum Slope /// \brief The slope that causes a trigger. diff --git a/openhantek/src/hantekdso/hantekdsocontrol.cpp b/openhantek/src/hantekdso/hantekdsocontrol.cpp index e4771a6..6d484b8 100644 --- a/openhantek/src/hantekdso/hantekdsocontrol.cpp +++ b/openhantek/src/hantekdso/hantekdsocontrol.cpp @@ -49,12 +49,6 @@ void HantekDsoControl::stopSampling() { emit samplingStopped(); } -const std::vector HantekDsoControl::getSpecialTriggerSources() { - std::vector sources; - for (auto &v : specification.specialTriggerChannels) { sources.push_back(v.name); } - return sources; -} - USBDevice *HantekDsoControl::getDevice() { return device; } const DSOsamples &HantekDsoControl::getLastSamples() { return result; } @@ -1236,7 +1230,7 @@ void HantekDsoControl::run() { // Sampling hasn't started, update the expected sample count expectedSampleCount = this->getSampleCount(); - if (this->_samplingStarted && this->lastTriggerMode == controlsettings.trigger.mode) { + if (_samplingStarted && lastTriggerMode == controlsettings.trigger.mode) { ++this->cycleCounter; if (this->cycleCounter == this->startCycle && !isRollMode()) { @@ -1252,8 +1246,8 @@ void HantekDsoControl::run() { } timestampDebug("Enabling trigger"); - } else if (this->cycleCounter >= 8 + this->startCycle && - controlsettings.trigger.mode == Dso::TriggerMode::AUTO) { + } else if (cycleCounter >= 8 + this->startCycle && + controlsettings.trigger.mode == Dso::TriggerMode::WAIT_FORCE) { // Force triggering errorCode = device->bulkCommand(getCommand(BulkCode::FORCETRIGGER)); if (errorCode < 0) { diff --git a/openhantek/src/hantekdso/hantekdsocontrol.h b/openhantek/src/hantekdso/hantekdsocontrol.h index 3fd3bf1..009fdba 100644 --- a/openhantek/src/hantekdso/hantekdsocontrol.h +++ b/openhantek/src/hantekdso/hantekdsocontrol.h @@ -74,9 +74,6 @@ class HantekDsoControl : public QObject { /// \return The maximum samplerate for the current configuration in S/s. double getMaxSamplerate(); - /// \brief Get a list of the names of the special trigger sources. - const std::vector getSpecialTriggerSources(); - /// Return the associated usb device. USBDevice *getDevice(); diff --git a/openhantek/src/hantekdso/models/modelDSO6022.cpp b/openhantek/src/hantekdso/models/modelDSO6022.cpp index 2db0205..4276e69 100644 --- a/openhantek/src/hantekdso/models/modelDSO6022.cpp +++ b/openhantek/src/hantekdso/models/modelDSO6022.cpp @@ -34,6 +34,7 @@ ModelDSO6022BE::ModelDSO6022BE() : DSOModel(ID, 0x04b5, 0x6022, 0x04b4, 0x6022, specification.sampleSize = 8; specification.couplings = {Dso::Coupling::DC}; + specification.triggerModes = {Dso::TriggerMode::HARDWARE_SOFTWARE, Dso::TriggerMode::SINGLE}; } void ModelDSO6022BE::applyRequirements(HantekDsoControl *dsoControl) const { diff --git a/openhantek/src/hantekdso/softwaretrigger.cpp b/openhantek/src/hantekdso/softwaretrigger.cpp index bdf78e1..7e6873d 100644 --- a/openhantek/src/hantekdso/softwaretrigger.cpp +++ b/openhantek/src/hantekdso/softwaretrigger.cpp @@ -1,28 +1,23 @@ #include "softwaretrigger.h" #include "analyse/dataanalyzerresult.h" -#include "settings.h" +#include "scopesettings.h" #include "viewconstants.h" #include "utils/printutils.h" -SoftwareTrigger::PrePostStartTriggerSamples SoftwareTrigger::computeTY(const DataAnalyzerResult *result, - const DsoSettingsScope *scope, - unsigned physicalChannels) +SoftwareTrigger::PrePostStartTriggerSamples SoftwareTrigger::compute(const DataAnalyzerResult *data, + const DsoSettingsScope *scope) { unsigned int preTrigSamples = 0; unsigned int postTrigSamples = 0; unsigned int swTriggerStart = 0; ChannelID channel = scope->trigger.source; - // check trigger point for software trigger - if (scope->trigger.mode != Dso::TriggerMode::SOFTWARE || channel >= physicalChannels) - return PrePostStartTriggerSamples(preTrigSamples, postTrigSamples, swTriggerStart); - // Trigger channel not in use - if (!scope->voltage[channel].used || !result->data(channel) || - result->data(channel)->voltage.sample.empty()) + if (!scope->voltage[channel].used || !data->data(channel) || + data->data(channel)->voltage.sample.empty()) return PrePostStartTriggerSamples(preTrigSamples, postTrigSamples, swTriggerStart); - const std::vector& samples = result->data(channel)->voltage.sample; + const std::vector& samples = data->data(channel)->voltage.sample; double level = scope->voltage[channel].trigger; size_t sampleCount = samples.size(); double timeDisplay = scope->horizontal.timebase * DIVS_TIME; diff --git a/openhantek/src/hantekdso/softwaretrigger.h b/openhantek/src/hantekdso/softwaretrigger.h index de9db8b..64d1ae3 100644 --- a/openhantek/src/hantekdso/softwaretrigger.h +++ b/openhantek/src/hantekdso/softwaretrigger.h @@ -3,11 +3,20 @@ struct DsoSettingsScope; class DataAnalyzerResult; -class SoftwareTrigger -{ -public: + +/** + * Contains software trigger algorithms. At the moment this works on the analysed data of the + * DataAnalyser class. + * TODO Should work on the raw data within HantekDsoControl + */ +class SoftwareTrigger { + public: typedef std::tuple PrePostStartTriggerSamples; - static PrePostStartTriggerSamples computeTY(const DataAnalyzerResult *result, - const DsoSettingsScope *scope, - unsigned physicalChannels); + /** + * @brief Computes a software trigger point. + * @param data Analysed data from the + * @param scope Scope settings + * @return Returns a tuple of positions [preTrigger, postTrigger, startTrigger] + */ + static PrePostStartTriggerSamples compute(const DataAnalyzerResult *data, const DsoSettingsScope *scope); }; diff --git a/openhantek/src/mainwindow.cpp b/openhantek/src/mainwindow.cpp index a4dae4a..75cbc89 100644 --- a/openhantek/src/mainwindow.cpp +++ b/openhantek/src/mainwindow.cpp @@ -17,6 +17,8 @@ #include "dsomodel.h" #include "viewconstants.h" +#include "settings.h" + #include #include #include @@ -38,7 +40,7 @@ MainWindow::MainWindow(HantekDsoControl *dsoControl, DataAnalyzer *dataAnalyser, registerDockMetaTypes(); horizontalDock = new HorizontalDock(&settings->scope, this); - triggerDock = new TriggerDock(settings, dsoControl->getSpecialTriggerSources(), this); + triggerDock = new TriggerDock(&settings->scope, settings->deviceSpecification, this); spectrumDock = new SpectrumDock(&settings->scope, this); voltageDock = new VoltageDock(&settings->scope, settings->deviceSpecification, this); diff --git a/openhantek/src/scopesettings.h b/openhantek/src/scopesettings.h index 6af8a19..b26a431 100644 --- a/openhantek/src/scopesettings.h +++ b/openhantek/src/scopesettings.h @@ -30,7 +30,7 @@ struct DsoSettingsScopeHorizontal { /// \brief Holds the settings for the trigger. /// TODO Use ControlSettingsTrigger struct DsoSettingsScopeTrigger { - Dso::TriggerMode mode = Dso::TriggerMode::NORMAL; ///< Automatic, normal or single trigger + Dso::TriggerMode mode = Dso::TriggerMode::HARDWARE_SOFTWARE; ///< Automatic, normal or single trigger double position = 0.0; ///< Horizontal position for pretrigger Dso::Slope slope = Dso::Slope::Positive; ///< Rising or falling edge causes trigger unsigned int source = 0; ///< Channel that is used as trigger source diff --git a/openhantek/src/utils/dsoStrings.cpp b/openhantek/src/utils/dsoStrings.cpp index 59c2c0b..1895c11 100644 --- a/openhantek/src/utils/dsoStrings.cpp +++ b/openhantek/src/utils/dsoStrings.cpp @@ -87,14 +87,12 @@ QString mathModeString(MathMode mode) { /// \return The string that should be used in labels etc. QString triggerModeString(TriggerMode mode) { switch (mode) { - case TriggerMode::AUTO: - return QApplication::tr("Auto"); - case TriggerMode::NORMAL: - return QApplication::tr("Normal"); + case TriggerMode::WAIT_FORCE: + return QApplication::tr("Wait/Force"); + case TriggerMode::HARDWARE_SOFTWARE: + return QApplication::tr("Hard-/Software"); case TriggerMode::SINGLE: return QApplication::tr("Single"); - case TriggerMode::SOFTWARE: - return QApplication::tr("Software"); } return QString(); }