SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
bladerf1inputgui.cpp
Go to the documentation of this file.
1 // Copyright (C) 2015 Edouard Griffiths, F4EXB //
3 // //
4 // This program is free software; you can redistribute it and/or modify //
5 // it under the terms of the GNU General Public License as published by //
6 // the Free Software Foundation as version 3 of the License, or //
7 // (at your option) any later version. //
8 // //
9 // This program is distributed in the hope that it will be useful, //
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of //
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
12 // GNU General Public License V3 for more details. //
13 // //
14 // You should have received a copy of the GNU General Public License //
15 // along with this program. If not, see <http://www.gnu.org/licenses/>. //
17 
18 #include <QDebug>
19 #include <QMessageBox>
20 
21 #include <libbladeRF.h>
22 
23 #include "ui_bladerf1inputgui.h"
24 #include "gui/colormapper.h"
25 #include "gui/glspectrum.h"
26 #include "gui/crightclickenabler.h"
28 #include "dsp/dspengine.h"
29 #include "dsp/dspcommands.h"
30 #include "device/deviceapi.h"
31 #include "device/deviceuiset.h"
32 
33 #include "bladerf1inputgui.h"
34 
35 Bladerf1InputGui::Bladerf1InputGui(DeviceUISet *deviceUISet, QWidget* parent) :
36  QWidget(parent),
37  ui(new Ui::Bladerf1InputGui),
38  m_deviceUISet(deviceUISet),
39  m_forceSettings(true),
40  m_doApplySettings(true),
41  m_settings(),
42  m_sampleRateMode(true),
43  m_sampleSource(NULL),
44  m_sampleRate(0),
45  m_lastEngineState(DeviceAPI::StNotStarted)
46 {
48 
49  ui->setupUi(this);
50  ui->centerFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
51  ui->centerFrequency->setValueRange(7, BLADERF_FREQUENCY_MIN_XB200/1000, BLADERF_FREQUENCY_MAX/1000);
52 
53  ui->sampleRate->setColorMapper(ColorMapper(ColorMapper::GrayGreenYellow));
54  // BladeRF can go as low as 80 kS/s but because of buffering in practice experience is not good below 330 kS/s
55  ui->sampleRate->setValueRange(8, 330000U, BLADERF_SAMPLERATE_REC_MAX);
56 
57  ui->bandwidth->clear();
58  for (unsigned int i = 0; i < BladerfBandwidths::getNbBandwidths(); i++)
59  {
60  ui->bandwidth->addItem(QString::number(BladerfBandwidths::getBandwidth(i)));
61  }
62 
63  connect(&m_updateTimer, SIGNAL(timeout()), this, SLOT(updateHardware()));
64  connect(&m_statusTimer, SIGNAL(timeout()), this, SLOT(updateStatus()));
65  m_statusTimer.start(500);
66 
67  CRightClickEnabler *startStopRightClickEnabler = new CRightClickEnabler(ui->startStop);
68  connect(startStopRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(openDeviceSettingsDialog(const QPoint &)));
69 
71 
72  connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection);
74 
75  sendSettings();
76 }
77 
79 {
80  delete ui;
81 }
82 
84 {
85  delete this;
86 }
87 
88 void Bladerf1InputGui::setName(const QString& name)
89 {
90  setObjectName(name);
91 }
92 
94 {
95  return objectName();
96 }
97 
99 {
101  displaySettings();
102  sendSettings();
103 }
104 
106 {
108 }
109 
110 void Bladerf1InputGui::setCenterFrequency(qint64 centerFrequency)
111 {
112  m_settings.m_centerFrequency = centerFrequency;
113  displaySettings();
114  sendSettings();
115 }
116 
117 QByteArray Bladerf1InputGui::serialize() const
118 {
119  return m_settings.serialize();
120 }
121 
122 bool Bladerf1InputGui::deserialize(const QByteArray& data)
123 {
124  if(m_settings.deserialize(data)) {
125  displaySettings();
126  m_forceSettings = true;
127  sendSettings();
128  return true;
129  } else {
130  resetToDefaults();
131  return false;
132  }
133 }
134 
136 {
138  {
140  m_settings = cfg.getSettings();
141  blockApplySettings(true);
142  displaySettings();
143  blockApplySettings(false);
144  return true;
145  }
146  else if (Bladerf1Input::MsgStartStop::match(message))
147  {
149  blockApplySettings(true);
150  ui->startStop->setChecked(notif.getStartStop());
151  blockApplySettings(false);
152 
153  return true;
154  }
155  else
156  {
157  return false;
158  }
159 }
160 
162 {
163  Message* message;
164 
165  while ((message = m_inputMessageQueue.pop()) != 0)
166  {
167  qDebug("BladerfGui::handleInputMessages: message: %s", message->getIdentifier());
168 
169  if (DSPSignalNotification::match(*message))
170  {
171  DSPSignalNotification* notif = (DSPSignalNotification*) message;
172  m_sampleRate = notif->getSampleRate();
174  qDebug("BladerfGui::handleInputMessages: DSPSignalNotification: SampleRate:%d, CenterFrequency:%llu", notif->getSampleRate(), notif->getCenterFrequency());
176 
177  delete message;
178  }
179  else
180  {
181  if (handleMessage(*message))
182  {
183  delete message;
184  }
185  }
186  }
187 }
188 
190 {
194 }
195 
197 {
198  ui->sampleRate->blockSignals(true);
200 
201  if (m_sampleRateMode)
202  {
203  ui->sampleRateMode->setStyleSheet("QToolButton { background:rgb(60,60,60); }");
204  ui->sampleRateMode->setText("SR");
205  // BladeRF can go as low as 80 kS/s but because of buffering in practice experience is not good below 330 kS/s
206  ui->sampleRate->setValueRange(8, 330000U, BLADERF_SAMPLERATE_REC_MAX);
207  ui->sampleRate->setValue(m_settings.m_devSampleRate);
208  ui->sampleRate->setToolTip("Device to host sample rate (S/s)");
209  ui->deviceRateText->setToolTip("Baseband sample rate (S/s)");
210  uint32_t basebandSampleRate = m_settings.m_devSampleRate/(1<<m_settings.m_log2Decim);
211  ui->deviceRateText->setText(tr("%1k").arg(QString::number(basebandSampleRate / 1000.0f, 'g', 5)));
212  }
213  else
214  {
215  ui->sampleRateMode->setStyleSheet("QToolButton { background:rgb(50,50,50); }");
216  ui->sampleRateMode->setText("BB");
217  // BladeRF can go as low as 80 kS/s but because of buffering in practice experience is not good below 330 kS/s
218  ui->sampleRate->setValueRange(8, 330000U/(1<<m_settings.m_log2Decim), BLADERF_SAMPLERATE_REC_MAX/(1<<m_settings.m_log2Decim));
219  ui->sampleRate->setValue(m_settings.m_devSampleRate/(1<<m_settings.m_log2Decim));
220  ui->sampleRate->setToolTip("Baseband sample rate (S/s)");
221  ui->deviceRateText->setToolTip("Device to host sample rate (S/s)");
222  ui->deviceRateText->setText(tr("%1k").arg(QString::number(m_settings.m_devSampleRate / 1000.0f, 'g', 5)));
223  }
224 
225  ui->sampleRate->blockSignals(false);
226 }
227 
229 {
234  DeviceSampleSource::FrequencyShiftScheme::FSHIFT_STD
235  );
236  ui->fcPos->setToolTip(tr("Relative position of device center frequency: %1 kHz").arg(QString::number(fShift / 1000.0f, 'g', 5)));
237 }
238 
240 {
241  blockApplySettings(true);
242 
243  ui->centerFrequency->setValue(m_settings.m_centerFrequency / 1000);
245 
246  ui->dcOffset->setChecked(m_settings.m_dcBlock);
247  ui->iqImbalance->setChecked(m_settings.m_iqCorrection);
248 
249  unsigned int bandwidthIndex = BladerfBandwidths::getBandwidthIndex(m_settings.m_bandwidth);
250  ui->bandwidth->setCurrentIndex(bandwidthIndex);
251 
252  ui->decim->setCurrentIndex(m_settings.m_log2Decim);
253 
254  ui->fcPos->setCurrentIndex((int) m_settings.m_fcPos);
255 
256  ui->lna->setCurrentIndex(m_settings.m_lnaGain);
257 
258  ui->vga1Text->setText(tr("%1dB").arg(m_settings.m_vga1));
259  ui->vga1->setValue(m_settings.m_vga1);
260 
261  ui->vga2Text->setText(tr("%1dB").arg(m_settings.m_vga2));
262  ui->vga2->setValue(m_settings.m_vga2);
263 
265 
266  blockApplySettings(false);
267 }
268 
270 {
271  if(!m_updateTimer.isActive())
272  m_updateTimer.start(100);
273 }
274 
276 {
277  m_settings.m_centerFrequency = value * 1000;
278  sendSettings();
279 }
280 
282 {
283  if (m_sampleRateMode) {
284  m_settings.m_devSampleRate = value;
285  } else {
287  }
288 
290  sendSettings();
291 }
292 
294 {
295  m_settings.m_dcBlock = checked;
296  sendSettings();
297 }
298 
300 {
301  m_settings.m_iqCorrection = checked;
302  sendSettings();
303 }
304 
306 {
307  int newbw = BladerfBandwidths::getBandwidth(index);
308  m_settings.m_bandwidth = newbw * 1000;
309  sendSettings();
310 }
311 
313 {
314  if ((index <0) || (index > 6)) {
315  return;
316  }
317 
318  m_settings.m_log2Decim = index;
320 
321  if (m_sampleRateMode) {
322  m_settings.m_devSampleRate = ui->sampleRate->getValueNew();
323  } else {
324  m_settings.m_devSampleRate = ui->sampleRate->getValueNew() * (1 << m_settings.m_log2Decim);
325  }
326 
327  sendSettings();
328 }
329 
331 {
332  m_settings.m_fcPos = (BladeRF1InputSettings::fcPos_t) (index < 0 ? 0 : index > 2 ? 2 : index);
334  sendSettings();
335 }
336 
338 {
339  qDebug() << "BladerfGui: LNA gain = " << index * 3 << " dB";
340 
341  if ((index < 0) || (index > 2))
342  return;
343 
344  m_settings.m_lnaGain = index;
345  sendSettings();
346 }
347 
349 {
350  if ((value < BLADERF_RXVGA1_GAIN_MIN) || (value > BLADERF_RXVGA1_GAIN_MAX))
351  return;
352 
353  ui->vga1Text->setText(tr("%1dB").arg(value));
354  m_settings.m_vga1 = value;
355  sendSettings();
356 }
357 
359 {
360  if ((value < BLADERF_RXVGA2_GAIN_MIN) || (value > BLADERF_RXVGA2_GAIN_MAX))
361  return;
362 
363  ui->vga2Text->setText(tr("%1dB").arg(value));
364  m_settings.m_vga2 = value;
365  sendSettings();
366 }
367 
369 {
370  if (index == 1) // bypass
371  {
372  m_settings.m_xb200 = true;
373  m_settings.m_xb200Path = BLADERF_XB200_BYPASS;
374  }
375  else if (index == 2) // Auto 1dB
376  {
377  m_settings.m_xb200 = true;
378  m_settings.m_xb200Path = BLADERF_XB200_MIX;
379  m_settings.m_xb200Filter = BLADERF_XB200_AUTO_1DB;
380  }
381  else if (index == 3) // Auto 3dB
382  {
383  m_settings.m_xb200 = true;
384  m_settings.m_xb200Path = BLADERF_XB200_MIX;
385  m_settings.m_xb200Filter = BLADERF_XB200_AUTO_3DB;
386  }
387  else if (index == 4) // Custom
388  {
389  m_settings.m_xb200 = true;
390  m_settings.m_xb200Path = BLADERF_XB200_MIX;
391  m_settings.m_xb200Filter = BLADERF_XB200_CUSTOM;
392  }
393  else if (index == 5) // 50 MHz
394  {
395  m_settings.m_xb200 = true;
396  m_settings.m_xb200Path = BLADERF_XB200_MIX;
397  m_settings.m_xb200Filter = BLADERF_XB200_50M;
398  }
399  else if (index == 6) // 144 MHz
400  {
401  m_settings.m_xb200 = true;
402  m_settings.m_xb200Path = BLADERF_XB200_MIX;
403  m_settings.m_xb200Filter = BLADERF_XB200_144M;
404  }
405  else if (index == 7) // 222 MHz
406  {
407  m_settings.m_xb200 = true;
408  m_settings.m_xb200Path = BLADERF_XB200_MIX;
409  m_settings.m_xb200Filter = BLADERF_XB200_222M;
410  }
411  else // no xb200
412  {
413  m_settings.m_xb200 = false;
414  }
415 
416  if (m_settings.m_xb200)
417  {
418  ui->centerFrequency->setValueRange(7, BLADERF_FREQUENCY_MIN_XB200/1000, BLADERF_FREQUENCY_MAX/1000);
419  }
420  else
421  {
422  ui->centerFrequency->setValueRange(7, BLADERF_FREQUENCY_MIN/1000, BLADERF_FREQUENCY_MAX/1000);
423  }
424 
425  sendSettings();
426 }
427 
429 {
430  if (m_doApplySettings)
431  {
434  }
435 }
436 
438 {
439  if (checked) {
440  ui->record->setStyleSheet("QToolButton { background-color : red; }");
441  } else {
442  ui->record->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
443  }
444 
447 }
448 
450 {
451  m_sampleRateMode = checked;
453 }
454 
456 {
457  if (m_doApplySettings)
458  {
459  qDebug() << "BladerfGui::updateHardware";
462  m_forceSettings = false;
463  m_updateTimer.stop();
464  }
465 }
466 
468 {
469  m_doApplySettings = !block;
470 }
471 
473 {
474  int state = m_deviceUISet->m_deviceAPI->state();
475 
476  if(m_lastEngineState != state)
477  {
478  switch(state)
479  {
481  ui->startStop->setStyleSheet("QToolButton { background:rgb(79,79,79); }");
482  break;
483  case DeviceAPI::StIdle:
484  ui->startStop->setStyleSheet("QToolButton { background-color : blue; }");
485  break;
487  ui->startStop->setStyleSheet("QToolButton { background-color : green; }");
488  break;
489  case DeviceAPI::StError:
490  ui->startStop->setStyleSheet("QToolButton { background-color : red; }");
491  QMessageBox::information(this, tr("Message"), m_deviceUISet->m_deviceAPI->errorMessage());
492  break;
493  default:
494  break;
495  }
496 
497  m_lastEngineState = state;
498  }
499 }
500 
501 unsigned int Bladerf1InputGui::getXb200Index(bool xb_200, bladerf_xb200_path xb200Path, bladerf_xb200_filter xb200Filter)
502 {
503  if (xb_200)
504  {
505  if (xb200Path == BLADERF_XB200_BYPASS)
506  {
507  return 1;
508  }
509  else
510  {
511  if (xb200Filter == BLADERF_XB200_AUTO_1DB)
512  {
513  return 2;
514  }
515  else if (xb200Filter == BLADERF_XB200_AUTO_3DB)
516  {
517  return 3;
518  }
519  else if (xb200Filter == BLADERF_XB200_CUSTOM)
520  {
521  return 4;
522  }
523  else if (xb200Filter == BLADERF_XB200_50M)
524  {
525  return 5;
526  }
527  else if (xb200Filter == BLADERF_XB200_144M)
528  {
529  return 6;
530  }
531  else // xb200Filter == BLADERF_XB200_222M
532  {
533  return 7;
534  }
535  }
536  }
537  else
538  {
539  return 0;
540  }
541 }
542 
544 {
545  BasicDeviceSettingsDialog dialog(this);
550 
551  dialog.move(p);
552  dialog.exec();
553 
558 
559  sendSettings();
560 }
Message * pop()
Pop message from queue.
const QString & getReverseAPIAddress() const
static qint32 calculateFrequencyShift(int log2Decim, fcPos_t fcPos, quint32 devSampleRate, FrequencyShiftScheme frequencyShiftScheme)
void push(Message *message, bool emitSignal=true)
Push message onto queue.
void setSampleRate(qint32 sampleRate)
Definition: glspectrum.cpp:211
void updateSampleRateAndFrequency()
void on_startStop_toggled(bool checked)
const BladeRF1InputSettings & getSettings() const
Definition: bladerf1input.h:45
void on_dcOffset_toggled(bool checked)
DeviceSampleSource * getSampleSource()
Return pointer to the device sample source (single Rx) or nullptr.
Definition: deviceapi.cpp:213
void setUseReverseAPI(bool useReverseAPI)
void on_vga1_valueChanged(int value)
MessageQueue * getInputMessageQueue()
virtual void destroy()
bladerf_xb200_filter m_xb200Filter
void on_centerFrequency_changed(quint64 value)
bool m_sampleRateMode
true: device, false: base band sample rate update mode
virtual bool handleMessage(const Message &message)
void on_fcPos_currentIndexChanged(int index)
void blockApplySettings(bool block)
virtual ~Bladerf1InputGui()
void on_vga2_valueChanged(int value)
QString errorMessage()
Last error message from the device engine.
Definition: deviceapi.cpp:290
DeviceSampleSource * m_sampleSource
void on_bandwidth_currentIndexChanged(int index)
static unsigned int getBandwidth(unsigned int bandwidth_index)
DeviceUISet * m_deviceUISet
unsigned int uint32_t
Definition: rtptypes_win.h:46
Fixed< IntType, IntBits > arg(const std::complex< Fixed< IntType, IntBits > > &val)
Definition: fixed.h:2401
void on_sampleRateMode_toggled(bool checked)
QByteArray serialize() const
QString getName() const
GLSpectrum * getSpectrum()
Direct spectrum getter.
Definition: deviceuiset.h:57
bladerf_xb200_path m_xb200Path
engine is before initialization
Definition: deviceapi.h:53
qint64 getCenterFrequency() const
Definition: dspcommands.h:329
EngineState state() const
Return the state of the device engine corresponding to the stream type.
Definition: deviceapi.cpp:277
void on_sampleRate_changed(quint64 value)
DeviceAPI * m_deviceAPI
Definition: deviceuiset.h:48
engine is idle
Definition: deviceapi.h:54
static MsgStartStop * create(bool startStop)
Definition: bladerf1input.h:89
unsigned int getXb200Index(bool xb_200, bladerf_xb200_path xb200Path, bladerf_xb200_filter xb200Filter)
int32_t i
Definition: decimators.h:244
virtual qint64 getCenterFrequency() const
static bool match(const Message *message)
Definition: message.cpp:45
int int32_t
Definition: rtptypes_win.h:45
bool deserialize(const QByteArray &data)
BladeRF1InputSettings m_settings
static MsgConfigureBladerf1 * create(const BladeRF1InputSettings &settings, bool force)
Definition: bladerf1input.h:48
static unsigned int getNbBandwidths()
static unsigned int getBandwidthIndex(unsigned int bandwidth)
void on_iqImbalance_toggled(bool checked)
void on_decim_currentIndexChanged(int index)
void setName(const QString &name)
int getSampleRate() const
Definition: dspcommands.h:328
bool deserialize(const QByteArray &data)
void on_xb200_currentIndexChanged(int index)
quint64 m_deviceCenterFrequency
Center frequency in device.
void on_lna_currentIndexChanged(int index)
void setCenterFrequency(qint64 frequency)
Definition: glspectrum.cpp:175
virtual const char * getIdentifier() const
Definition: message.cpp:35
void openDeviceSettingsDialog(const QPoint &p)
void setReverseAPIAddress(const QString &address)
virtual void setCenterFrequency(qint64 centerFrequency)
void setReverseAPIDeviceIndex(uint16_t deviceIndex)
virtual void setMessageQueueToGUI(MessageQueue *queue)=0
engine is running
Definition: deviceapi.h:56
void on_record_toggled(bool checked)
QByteArray serialize() const
Ui::Bladerf1InputGui * ui
engine is in error
Definition: deviceapi.h:57
MessageQueue m_inputMessageQueue
Bladerf1InputGui(DeviceUISet *deviceUISet, QWidget *parent=0)
static MsgFileRecord * create(bool startStop)
Definition: bladerf1input.h:70