diff --git a/Readme.md b/Readme.md
index 3b05ec01c..cf284de5b 100644
--- a/Readme.md
+++ b/Readme.md
@@ -118,6 +118,7 @@ Done since the fork
- Implemented scope pre-trigger delay
- Implemented variable scope memory depth
- Implemented trigger delay
+ - Trigger on both edges
=====
To Do
diff --git a/include-gpl/dsp/scopevis.h b/include-gpl/dsp/scopevis.h
index 04804b0e9..6697d53cf 100644
--- a/include-gpl/dsp/scopevis.h
+++ b/include-gpl/dsp/scopevis.h
@@ -28,6 +28,7 @@ public:
TriggerChannel triggerChannel,
Real triggerLevel,
bool triggerPositiveEdge,
+ bool triggerBothEdges,
uint triggerPre,
uint triggerDelay,
uint traceSize);
@@ -51,6 +52,7 @@ private:
int getTriggerChannel() const { return m_triggerChannel; }
Real getTriggerLevel() const { return m_triggerLevel; }
Real getTriggerPositiveEdge() const { return m_triggerPositiveEdge; }
+ Real getTriggerBothEdges() const { return m_triggerBothEdges; }
uint getTriggerPre() const { return m_triggerPre; }
uint getTriggerDelay() const { return m_triggerDelay; }
uint getTraceSize() const { return m_traceSize; }
@@ -58,17 +60,25 @@ private:
static MsgConfigureScopeVis* create(int triggerChannel,
Real triggerLevel,
bool triggerPositiveEdge,
+ bool triggerBothEdges,
uint triggerPre,
uint triggerDelay,
uint traceSize)
{
- return new MsgConfigureScopeVis(triggerChannel, triggerLevel, triggerPositiveEdge, triggerPre, triggerDelay, traceSize);
+ return new MsgConfigureScopeVis(triggerChannel,
+ triggerLevel,
+ triggerPositiveEdge,
+ triggerBothEdges,
+ triggerPre,
+ triggerDelay,
+ traceSize);
}
private:
int m_triggerChannel;
Real m_triggerLevel;
bool m_triggerPositiveEdge;
+ bool m_triggerBothEdges;
uint m_triggerPre;
uint m_triggerDelay;
uint m_traceSize;
@@ -76,6 +86,7 @@ private:
MsgConfigureScopeVis(int triggerChannel,
Real triggerLevel,
bool triggerPositiveEdge,
+ bool triggerBothEdges,
uint triggerPre,
uint triggerDelay,
uint traceSize) :
@@ -83,6 +94,7 @@ private:
m_triggerChannel(triggerChannel),
m_triggerLevel(triggerLevel),
m_triggerPositiveEdge(triggerPositiveEdge),
+ m_triggerBothEdges(triggerBothEdges),
m_triggerPre(triggerPre),
m_triggerDelay(triggerDelay),
m_traceSize(traceSize)
@@ -119,6 +131,8 @@ private:
TriggerChannel m_triggerChannel;
Real m_triggerLevel;
bool m_triggerPositiveEdge;
+ bool m_triggerBothEdges;
+ bool m_prevTrigger;
uint m_triggerPre; //!< Pre-trigger delay in number of samples
bool m_triggerOneShot;
bool m_armed;
diff --git a/include-gpl/gui/glscopegui.h b/include-gpl/gui/glscopegui.h
index 8ba9b0aef..649d9f726 100644
--- a/include-gpl/gui/glscopegui.h
+++ b/include-gpl/gui/glscopegui.h
@@ -51,6 +51,7 @@ private:
qint32 m_triggerChannel;
qint32 m_triggerLevel; // percent
bool m_triggerPositiveEdge;
+ bool m_triggerBothEdges;
qint32 m_triggerPre;
qint32 m_triggerDelay;
qint32 m_traceLenMult;
@@ -90,6 +91,7 @@ private slots:
void on_trigMode_currentIndexChanged(int index);
void on_slopePos_clicked();
void on_slopeNeg_clicked();
+ void on_slopeBoth_clicked();
void on_oneShot_clicked();
void on_trigLevel_valueChanged(int value);
};
diff --git a/sdrbase/dsp/scopevis.cpp b/sdrbase/dsp/scopevis.cpp
index 3a8447cf1..94454345b 100644
--- a/sdrbase/dsp/scopevis.cpp
+++ b/sdrbase/dsp/scopevis.cpp
@@ -19,6 +19,7 @@ ScopeVis::ScopeVis(GLScope* glScope) :
m_triggerChannel(TriggerFreeRun),
m_triggerLevel(0.0),
m_triggerPositiveEdge(true),
+ m_triggerBothEdges(false),
m_triggerPre(0),
m_triggerDelay(0),
m_triggerDelayCount(0),
@@ -35,11 +36,18 @@ void ScopeVis::configure(MessageQueue* msgQueue,
TriggerChannel triggerChannel,
Real triggerLevel,
bool triggerPositiveEdge,
+ bool triggerBothEdges,
uint triggerPre,
uint triggerDelay,
uint traceSize)
{
- Message* cmd = MsgConfigureScopeVis::create(triggerChannel, triggerLevel, triggerPositiveEdge, triggerPre, triggerDelay, traceSize);
+ Message* cmd = MsgConfigureScopeVis::create(triggerChannel,
+ triggerLevel,
+ triggerPositiveEdge,
+ triggerBothEdges,
+ triggerPre,
+ triggerDelay,
+ traceSize);
cmd->submit(msgQueue, this);
}
@@ -113,10 +121,19 @@ void ScopeVis::feed(SampleVector::const_iterator begin, SampleVector::const_iter
{
while(begin < end)
{
- bool trigger = triggerCondition(begin);
+ bool triggerCdt = triggerCondition(begin);
+
if (m_tracebackCount > m_triggerPre)
{
- if (trigger ^ !m_triggerPositiveEdge)
+ bool trigger;
+
+ if (m_triggerBothEdges) {
+ trigger = m_prevTrigger ^ triggerCdt;
+ } else {
+ trigger = triggerCdt ^ !m_triggerPositiveEdge;
+ }
+
+ if (trigger)
{
if (m_armed)
{
@@ -145,6 +162,7 @@ void ScopeVis::feed(SampleVector::const_iterator begin, SampleVector::const_iter
m_armed = true;
}
}
+ m_prevTrigger = triggerCdt;
++begin;
}
}
@@ -199,6 +217,7 @@ bool ScopeVis::handleMessageKeep(Message* message)
m_triggerChannel = (TriggerChannel) conf->getTriggerChannel();
m_triggerLevel = conf->getTriggerLevel();
m_triggerPositiveEdge = conf->getTriggerPositiveEdge();
+ m_triggerBothEdges = conf->getTriggerBothEdges();
m_triggerPre = conf->getTriggerPre();
if (m_triggerPre >= m_traceback.size()) {
m_triggerPre = m_traceback.size() - 1; // top sample in FIFO is always the triggering one (pre-trigger delay = 0)
@@ -215,6 +234,7 @@ bool ScopeVis::handleMessageKeep(Message* message)
<< " m_triggerChannel: " << m_triggerChannel
<< " m_triggerLevel: " << m_triggerLevel
<< " m_triggerPositiveEdge: " << (m_triggerPositiveEdge ? "edge+" : "edge-")
+ << " m_triggerBothEdges: " << (m_triggerBothEdges ? "yes" : "no")
<< " m_preTrigger: " << m_triggerPre
<< " m_triggerDelay: " << m_triggerDelay
<< " m_traceSize: " << m_trace.size() << std::endl;
diff --git a/sdrbase/gui/glscopegui.cpp b/sdrbase/gui/glscopegui.cpp
index 7423d0243..b9ccae351 100644
--- a/sdrbase/gui/glscopegui.cpp
+++ b/sdrbase/gui/glscopegui.cpp
@@ -28,6 +28,7 @@ GLScopeGUI::GLScopeGUI(QWidget* parent) :
m_triggerChannel(ScopeVis::TriggerFreeRun),
m_triggerLevel(0.0),
m_triggerPositiveEdge(true),
+ m_triggerBothEdges(false),
m_triggerPre(0),
m_triggerDelay(0),
m_traceLenMult(20)
@@ -91,6 +92,7 @@ QByteArray GLScopeGUI::serialize() const
s.writeS32(13, m_triggerPre);
s.writeS32(14, m_traceLenMult);
s.writeS32(15, m_triggerDelay);
+ s.writeBool(16, m_triggerBothEdges);
return s.final();
}
@@ -121,8 +123,6 @@ bool GLScopeGUI::deserialize(const QByteArray& data)
ui->trigLevel->setValue(m_triggerLevel);
setTrigLevelDisplay();
d.readBool(11, &m_triggerPositiveEdge, true);
- ui->slopePos->setChecked(m_triggerPositiveEdge);
- ui->slopeNeg->setChecked(!m_triggerPositiveEdge);
d.readS32(12, &m_displayTraceIntensity, 50);
d.readS32(13, &m_triggerPre, 0);
ui->trigPre->setValue(m_triggerPre);
@@ -133,6 +133,16 @@ bool GLScopeGUI::deserialize(const QByteArray& data)
d.readS32(15, &m_triggerDelay, 0);
ui->trigDelay->setValue(m_triggerDelay);
setTrigDelayDisplay();
+ d.readBool(16, &m_triggerBothEdges, false);
+ if (m_triggerBothEdges) {
+ ui->slopePos->setChecked(false);
+ ui->slopeNeg->setChecked(false);
+ ui->slopeBoth->setChecked(true);
+ } else {
+ ui->slopeBoth->setChecked(false);
+ ui->slopePos->setChecked(m_triggerPositiveEdge);
+ ui->slopeNeg->setChecked(!m_triggerPositiveEdge);
+ }
applySettings();
applyTriggerSettings();
return true;
@@ -204,6 +214,7 @@ void GLScopeGUI::applyTriggerSettings()
(ScopeVis::TriggerChannel) m_triggerChannel,
triggerLevel,
m_triggerPositiveEdge,
+ m_triggerBothEdges,
preTriggerSamples,
m_triggerDelay,
m_traceLenMult * ScopeVis::m_traceChunkSize);
@@ -546,6 +557,9 @@ void GLScopeGUI::on_trigLevel_valueChanged(int value)
void GLScopeGUI::on_slopePos_clicked()
{
m_triggerPositiveEdge = true;
+ m_triggerBothEdges = false;
+
+ ui->slopeBoth->setChecked(false);
if(ui->slopePos->isChecked()) {
ui->slopeNeg->setChecked(false);
@@ -559,6 +573,9 @@ void GLScopeGUI::on_slopePos_clicked()
void GLScopeGUI::on_slopeNeg_clicked()
{
m_triggerPositiveEdge = false;
+ m_triggerBothEdges = false;
+
+ ui->slopeBoth->setChecked(false);
if(ui->slopeNeg->isChecked()) {
ui->slopePos->setChecked(false);
@@ -569,6 +586,17 @@ void GLScopeGUI::on_slopeNeg_clicked()
applyTriggerSettings();
}
+void GLScopeGUI::on_slopeBoth_clicked()
+{
+ std::cerr << "GLScopeGUI::on_slopeBoth_clicked" << std::endl;
+ ui->slopePos->setChecked(false);
+ ui->slopeNeg->setChecked(false);
+ ui->slopeBoth->setChecked(true);
+ m_triggerBothEdges = true;
+
+ applyTriggerSettings();
+}
+
void GLScopeGUI::on_oneShot_clicked()
{
m_scopeVis->setOneShot(ui->oneShot->isChecked());
diff --git a/sdrbase/gui/glscopegui.ui b/sdrbase/gui/glscopegui.ui
index 9e5e88e55..c10420662 100644
--- a/sdrbase/gui/glscopegui.ui
+++ b/sdrbase/gui/glscopegui.ui
@@ -571,7 +571,7 @@
- Trigger slope positive
+ Trigger positive edge
@@ -608,7 +608,7 @@
- Trigger slope negative
+ Trigger negative edge
@@ -631,6 +631,35 @@
+ -
+
+
+ Trigger on both edges
+
+
+
+
+
+
+ :/slopeb_icon.png:/slopeb_icon.png
+
+
+
+ 16
+ 16
+
+
+
+ true
+
+
+ false
+
+
+ true
+
+
+
-
diff --git a/sdrbase/resources/res.qrc b/sdrbase/resources/res.qrc
index 21207a6b6..6c71bf785 100644
--- a/sdrbase/resources/res.qrc
+++ b/sdrbase/resources/res.qrc
@@ -23,5 +23,6 @@
horizontal_w.png
vertical_w.png
current.png
+ slopeb_icon.png
diff --git a/sdrbase/resources/slopeb_icon.png b/sdrbase/resources/slopeb_icon.png
new file mode 100644
index 000000000..bdfccbdea
Binary files /dev/null and b/sdrbase/resources/slopeb_icon.png differ