diff --git a/plugins/samplemimo/bladerf2mimo/bladerf2mimo.cpp b/plugins/samplemimo/bladerf2mimo/bladerf2mimo.cpp index 5e5a06566..f6c079273 100644 --- a/plugins/samplemimo/bladerf2mimo/bladerf2mimo.cpp +++ b/plugins/samplemimo/bladerf2mimo/bladerf2mimo.cpp @@ -51,7 +51,7 @@ BladeRF2MIMO::BladeRF2MIMO(DeviceAPI *deviceAPI) : m_sourceThread(nullptr), m_sinkThread(nullptr), m_deviceDescription("BladeRF2MIMO"), - m_rxElseTx(true), + m_startStopRxElseTx(true), m_runningRx(false), m_runningTx(false), m_dev(nullptr), @@ -74,7 +74,9 @@ BladeRF2MIMO::BladeRF2MIMO(DeviceAPI *deviceAPI) : m_mimoType = MIMOHalfSynchronous; m_sampleMIFifo.init(2, 96000 * 4); + m_sampleMOFifo.init(2, 96000 * 4); m_deviceAPI->setNbSourceStreams(2); + m_deviceAPI->setNbSinkStreams(2); m_networkManager = new QNetworkAccessManager(); connect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); } @@ -84,9 +86,7 @@ BladeRF2MIMO::~BladeRF2MIMO() disconnect(m_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkManagerFinished(QNetworkReply*))); delete m_networkManager; - if (m_runningRx) { - stop(); - } + closeDevice(); std::vector::iterator it = m_fileSinks.begin(); int istream = 0; @@ -128,12 +128,17 @@ void BladeRF2MIMO::closeDevice() } if (m_runningRx) { - stop(); + stopRx(); + } + + if (m_runningTx) { + stopTx(); } m_dev->close(); delete m_dev; m_dev = nullptr; + m_open = false; } void BladeRF2MIMO::init() @@ -154,7 +159,7 @@ bool BladeRF2MIMO::start() applySettings(m_settings, true); - if (m_rxElseTx) { + if (m_startStopRxElseTx) { startRx(); } else { startTx(); @@ -165,23 +170,23 @@ bool BladeRF2MIMO::start() void BladeRF2MIMO::startRx() { - qDebug("BladeRF2MIMO::start"); + qDebug("BladeRF2MIMO::startRx"); QMutexLocker mutexLocker(&m_mutex); if (m_runningRx) { - stop(); + stopRx(); } m_sourceThread = new BladeRF2MIThread(m_dev->getDev()); m_sampleMIFifo.reset(); m_sourceThread->setFifo(&m_sampleMIFifo); - m_sourceThread->setFcPos(m_settings.m_fcPos); + m_sourceThread->setFcPos(m_settings.m_fcPosRx); m_sourceThread->setLog2Decimation(m_settings.m_log2Decim); for (int i = 0; i < 2; i++) { if (!m_dev->openRx(i)) { - qCritical("BladeRF2MIMO::start: Rx channel %u cannot be enabled", i); + qCritical("BladeRF2MIMO::startRx: Rx channel %u cannot be enabled", i); } } @@ -192,12 +197,34 @@ void BladeRF2MIMO::startRx() void BladeRF2MIMO::startTx() { - // TODO + qDebug("BladeRF2MIMO::startTx"); + QMutexLocker mutexLocker(&m_mutex); + + if (m_runningTx) { + stopTx(); + } + + m_sinkThread = new BladeRF2MOThread(m_dev->getDev()); + m_sampleMOFifo.reset(); + m_sinkThread->setFifo(&m_sampleMOFifo); + m_sinkThread->setFcPos(m_settings.m_fcPosTx); + m_sinkThread->setLog2Interpolation(m_settings.m_log2Interp); + + for (int i = 0; i < 2; i++) + { + if (!m_dev->openRx(i)) { + qCritical("BladeRF2MIMO::startTx: Rx channel %u cannot be enabled", i); + } + } + + m_sourceThread->startWork(); + mutexLocker.unlock(); + m_runningRx = true; } void BladeRF2MIMO::stop() { - if (m_rxElseTx) { + if (m_startStopRxElseTx) { stopRx(); } else { stopTx(); @@ -206,7 +233,7 @@ void BladeRF2MIMO::stop() void BladeRF2MIMO::stopRx() { - qDebug("BladeRF2MIMO::stop"); + qDebug("BladeRF2MIMO::stopRx"); if (!m_sourceThread) { return; @@ -226,7 +253,22 @@ void BladeRF2MIMO::stopRx() void BladeRF2MIMO::stopTx() { - // TODO + qDebug("BladeRF2MIMO::stopTx"); + + if (!m_sinkThread) { + return; + } + + QMutexLocker mutexLocker(&m_mutex); + + m_sinkThread->stopWork(); + delete m_sinkThread; + m_sinkThread = nullptr; + m_runningTx = false; + + for (int i = 0; i < 2; i++) { + m_dev->closeTx(i); + } } QByteArray BladeRF2MIMO::serialize() const @@ -364,17 +406,22 @@ bool BladeRF2MIMO::handleMessage(const Message& message) << " " << (cmd.getRxElseTx() ? "Rx" : "Tx") << " MsgStartStop: " << (cmd.getStartStop() ? "start" : "stop"); - m_rxElseTx = cmd.getRxElseTx(); + m_startStopRxElseTx = cmd.getRxElseTx(); - if (cmd.getStartStop()) + if (cmd.getStartStop()) // start engine if not started yet { - if (m_deviceAPI->initDeviceEngine()) { - m_deviceAPI->startDeviceEngine(); + if ((m_deviceAPI->state() == DeviceAPI::StNotStarted) || (m_deviceAPI->state() == DeviceAPI::StIdle)) + { + if (m_deviceAPI->initDeviceEngine()) { + m_deviceAPI->startDeviceEngine(); + } } } - else + else // stop engine if the other part is not running { - m_deviceAPI->stopDeviceEngine(); + if ((m_startStopRxElseTx && !m_runningTx) || (!m_startStopRxElseTx && m_runningRx)) { + m_deviceAPI->stopDeviceEngine(); + } } if (m_settings.m_useReverseAPI) { @@ -400,7 +447,7 @@ bool BladeRF2MIMO::applySettings(const BladeRF2MIMOSettings& settings, bool forc << " m_LOppmTenths: " << settings.m_LOppmTenths << " m_rxCenterFrequency: " << settings.m_rxCenterFrequency << " m_log2Decim: " << settings.m_log2Decim - << " m_fcPos: " << settings.m_fcPos + << " m_fcPosRx: " << settings.m_fcPosRx << " m_rxBandwidth: " << settings.m_rxBandwidth << " m_rx0GainMode: " << settings.m_rx0GainMode << " m_rx0GlobalGain: " << settings.m_rx0GlobalGain @@ -413,6 +460,7 @@ bool BladeRF2MIMO::applySettings(const BladeRF2MIMOSettings& settings, bool forc << " m_rxTransverterDeltaFrequency: " << settings.m_rxTransverterDeltaFrequency << " m_txCenterFrequency: " << settings.m_txCenterFrequency << " m_log2Interp: " << settings.m_log2Interp + << " m_fcPosTx: " << settings.m_fcPosTx << " m_txBandwidth: " << settings.m_txBandwidth << " m_tx0GlobalGain: " << settings.m_tx0GlobalGain << " m_tx1GlobalGain: " << settings.m_tx1GlobalGain @@ -500,14 +548,14 @@ bool BladeRF2MIMO::applySettings(const BladeRF2MIMOSettings& settings, bool forc } } - if ((m_settings.m_fcPos != settings.m_fcPos) || force) + if ((m_settings.m_fcPosRx != settings.m_fcPosRx) || force) { - reverseAPIKeys.append("fcPos"); + reverseAPIKeys.append("fcPosRx"); if (m_sourceThread) { - m_sourceThread->setFcPos((int) settings.m_fcPos); - qDebug() << "BladeRF2MIMO::applySettings: set fc pos (enum) to " << (int) settings.m_fcPos; + m_sourceThread->setFcPos((int) settings.m_fcPosRx); + qDebug() << "BladeRF2MIMO::applySettings: set Rx fc pos (enum) to " << (int) settings.m_fcPosRx; } } @@ -522,6 +570,17 @@ bool BladeRF2MIMO::applySettings(const BladeRF2MIMOSettings& settings, bool forc } } + if ((m_settings.m_fcPosTx != settings.m_fcPosTx) || force) + { + reverseAPIKeys.append("fcPosTx"); + + if (m_sourceThread) + { + m_sourceThread->setFcPos((int) settings.m_fcPosTx); + qDebug() << "BladeRF2MIMO::applySettings: set Tx fc pos (enum) to " << (int) settings.m_fcPosTx; + } + } + if ((m_settings.m_log2Interp != settings.m_log2Interp) || force) { reverseAPIKeys.append("log2Interp"); @@ -551,14 +610,14 @@ bool BladeRF2MIMO::applySettings(const BladeRF2MIMOSettings& settings, bool forc || (m_settings.m_rxTransverterDeltaFrequency != settings.m_rxTransverterDeltaFrequency) || (m_settings.m_LOppmTenths != settings.m_LOppmTenths) || (m_settings.m_devSampleRate != settings.m_devSampleRate) - || (m_settings.m_fcPos != settings.m_fcPos) + || (m_settings.m_fcPosRx != settings.m_fcPosRx) || (m_settings.m_log2Decim != settings.m_log2Decim) || force) { qint64 deviceCenterFrequency = DeviceSampleSource::calculateDeviceCenterFrequency( rxXlatedDeviceCenterFrequency, 0, settings.m_log2Decim, - (DeviceSampleSource::fcPos_t) settings.m_fcPos, + (DeviceSampleSource::fcPos_t) settings.m_fcPosRx, settings.m_devSampleRate, DeviceSampleSource::FrequencyShiftScheme::FSHIFT_STD, false); @@ -678,6 +737,7 @@ bool BladeRF2MIMO::applySettings(const BladeRF2MIMOSettings& settings, bool forc if ((m_settings.m_txCenterFrequency != settings.m_txCenterFrequency) || (m_settings.m_txTransverterMode != settings.m_txTransverterMode) || (m_settings.m_txTransverterDeltaFrequency != settings.m_txTransverterDeltaFrequency) + || (m_settings.m_fcPosTx != settings.m_fcPosTx) || (m_settings.m_LOppmTenths != settings.m_LOppmTenths) || (m_settings.m_devSampleRate != settings.m_devSampleRate) || force) { @@ -687,7 +747,7 @@ bool BladeRF2MIMO::applySettings(const BladeRF2MIMOSettings& settings, bool forc settings.m_txCenterFrequency, settings.m_txTransverterDeltaFrequency, settings.m_log2Interp, - (DeviceSampleSink::fcPos_t) DeviceSampleSink::FC_POS_CENTER, + (DeviceSampleSink::fcPos_t) settings.m_fcPosTx, settings.m_devSampleRate, settings.m_txTransverterMode); @@ -1004,8 +1064,8 @@ void BladeRF2MIMO::webapiUpdateDeviceSettings( if (deviceSettingsKeys.contains("log2Decim")) { settings.m_log2Decim = response.getBladeRf2MimoSettings()->getLog2Decim(); } - if (deviceSettingsKeys.contains("fcPos")) { - settings.m_fcPos = static_cast(response.getBladeRf2MimoSettings()->getFcPos()); + if (deviceSettingsKeys.contains("fcPosRx")) { + settings.m_fcPosRx = static_cast(response.getBladeRf2MimoSettings()->getFcPosRx()); } if (deviceSettingsKeys.contains("rxBandwidth")) { settings.m_rxBandwidth = response.getBladeRf2MimoSettings()->getRxBandwidth(); @@ -1044,6 +1104,9 @@ void BladeRF2MIMO::webapiUpdateDeviceSettings( if (deviceSettingsKeys.contains("log2Interp")) { settings.m_log2Interp = response.getBladeRf2MimoSettings()->getLog2Interp(); } + if (deviceSettingsKeys.contains("fcPosTx")) { + settings.m_fcPosRx = static_cast(response.getBladeRf2MimoSettings()->getFcPosTx()); + } if (deviceSettingsKeys.contains("txBandwidth")) { settings.m_txBandwidth = response.getBladeRf2MimoSettings()->getTxBandwidth(); } @@ -1087,7 +1150,7 @@ void BladeRF2MIMO::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& re response.getBladeRf2MimoSettings()->setRxCenterFrequency(settings.m_rxCenterFrequency); response.getBladeRf2MimoSettings()->setLog2Decim(settings.m_log2Decim); - response.getBladeRf2MimoSettings()->setFcPos((int) settings.m_fcPos); + response.getBladeRf2MimoSettings()->setFcPosRx((int) settings.m_fcPosRx); response.getBladeRf2MimoSettings()->setRxBandwidth(settings.m_rxBandwidth); response.getBladeRf2MimoSettings()->setRx0GainMode(settings.m_rx0GainMode); response.getBladeRf2MimoSettings()->setRx0GlobalGain(settings.m_rx0GlobalGain); @@ -1101,6 +1164,7 @@ void BladeRF2MIMO::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& re response.getBladeRf2MimoSettings()->setTxCenterFrequency(settings.m_txCenterFrequency); response.getBladeRf2MimoSettings()->setLog2Interp(settings.m_log2Interp); + response.getBladeRf2MimoSettings()->setFcPosTx((int) settings.m_fcPosTx); response.getBladeRf2MimoSettings()->setTxBandwidth(settings.m_txBandwidth); response.getBladeRf2MimoSettings()->setTx0GlobalGain(settings.m_tx0GlobalGain); response.getBladeRf2MimoSettings()->setTx1GlobalGain(settings.m_tx1GlobalGain); @@ -1178,8 +1242,8 @@ void BladeRF2MIMO::webapiReverseSendSettings(QList& deviceSettingsKeys, if (deviceSettingsKeys.contains("log2Decim") || force) { swgBladeRF2MIMOSettings->setLog2Decim(settings.m_log2Decim); } - if (deviceSettingsKeys.contains("fcPos") || force) { - swgBladeRF2MIMOSettings->setFcPos((int) settings.m_fcPos); + if (deviceSettingsKeys.contains("fcPosRx") || force) { + swgBladeRF2MIMOSettings->setFcPosRx((int) settings.m_fcPosRx); } if (deviceSettingsKeys.contains("rxBandwidth") || force) { swgBladeRF2MIMOSettings->setRxBandwidth(settings.m_rxBandwidth); @@ -1218,6 +1282,9 @@ void BladeRF2MIMO::webapiReverseSendSettings(QList& deviceSettingsKeys, if (deviceSettingsKeys.contains("log2Interp") || force) { swgBladeRF2MIMOSettings->setLog2Interp(settings.m_log2Interp); } + if (deviceSettingsKeys.contains("fcPosTx") || force) { + swgBladeRF2MIMOSettings->setFcPosTx((int) settings.m_fcPosTx); + } if (deviceSettingsKeys.contains("txBandwidth") || force) { swgBladeRF2MIMOSettings->setTxBandwidth(settings.m_txBandwidth); } diff --git a/plugins/samplemimo/bladerf2mimo/bladerf2mimo.h b/plugins/samplemimo/bladerf2mimo/bladerf2mimo.h index 212831012..97e572a3d 100644 --- a/plugins/samplemimo/bladerf2mimo/bladerf2mimo.h +++ b/plugins/samplemimo/bladerf2mimo/bladerf2mimo.h @@ -212,6 +212,9 @@ public: void getTxBandwidthRange(int& min, int& max, int& step); void getTxGlobalGainRange(int& min, int& max, int& step); + bool getRxRunning() const { return m_runningRx; } + bool getTxRunning() const { return m_runningTx; } + private: DeviceAPI *m_deviceAPI; std::vector m_fileSinks; //!< File sinks to record device I/Q output @@ -220,7 +223,7 @@ private: BladeRF2MIThread* m_sourceThread; BladeRF2MOThread* m_sinkThread; QString m_deviceDescription; - bool m_rxElseTx; + bool m_startStopRxElseTx; bool m_runningRx; bool m_runningTx; QNetworkAccessManager *m_networkManager; diff --git a/plugins/samplemimo/bladerf2mimo/bladerf2mimogui.cpp b/plugins/samplemimo/bladerf2mimo/bladerf2mimogui.cpp index f6c4c1a42..5b4c0848c 100644 --- a/plugins/samplemimo/bladerf2mimo/bladerf2mimogui.cpp +++ b/plugins/samplemimo/bladerf2mimo/bladerf2mimogui.cpp @@ -90,7 +90,7 @@ BladeRF2MIMOGui::BladeRF2MIMOGui(DeviceUISet *deviceUISet, QWidget* parent) : connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()), Qt::QueuedConnection); m_sampleMIMO->setMessageQueueToGUI(&m_inputMessageQueue); - CRightClickEnabler *startStopRightClickEnabler = new CRightClickEnabler(ui->startStop); + CRightClickEnabler *startStopRightClickEnabler = new CRightClickEnabler(ui->startStopRx); connect(startStopRightClickEnabler, SIGNAL(rightClick(const QPoint &)), this, SLOT(openDeviceSettingsDialog(const QPoint &))); } @@ -173,6 +173,7 @@ void BladeRF2MIMOGui::displaySettings() ui->label_decim->setText(QString("Dec")); ui->decim->setToolTip(QString("Decimation factor")); ui->gainMode->setEnabled(true); + ui->fcPos->setCurrentIndex((int) m_settings.m_fcPosRx); if (m_streamIndex == 0) { @@ -205,6 +206,7 @@ void BladeRF2MIMOGui::displaySettings() ui->label_decim->setText(QString("Int")); ui->decim->setToolTip(QString("Interpolation factor")); ui->gainMode->setEnabled(false); + ui->fcPos->setCurrentIndex((int) m_settings.m_fcPosTx); if (m_streamIndex == 0) { @@ -221,7 +223,6 @@ void BladeRF2MIMOGui::displaySettings() ui->sampleRate->setValue(m_settings.m_devSampleRate); ui->LOppm->setValue(m_settings.m_LOppmTenths); ui->LOppmText->setText(QString("%1").arg(QString::number(m_settings.m_LOppmTenths/10.0, 'f', 1))); - ui->fcPos->setCurrentIndex((int) m_settings.m_fcPos); displaySampleRate(); } @@ -267,7 +268,7 @@ void BladeRF2MIMOGui::displayFcTooltip() { fShift = DeviceSampleStatic::calculateSourceFrequencyShift( m_settings.m_log2Decim, - (DeviceSampleStatic::fcPos_t) m_settings.m_fcPos, + (DeviceSampleStatic::fcPos_t) m_settings.m_fcPosRx, m_settings.m_devSampleRate, DeviceSampleStatic::FrequencyShiftScheme::FSHIFT_STD ); @@ -275,8 +276,8 @@ void BladeRF2MIMOGui::displayFcTooltip() else { fShift = DeviceSampleStatic::calculateSinkFrequencyShift( - m_settings.m_log2Decim, - (DeviceSampleStatic::fcPos_t) m_settings.m_fcPos, + m_settings.m_log2Interp, + (DeviceSampleStatic::fcPos_t) m_settings.m_fcPosTx, m_settings.m_devSampleRate ); } @@ -300,6 +301,7 @@ void BladeRF2MIMOGui::displayGainModes() else { ui->gainMode->clear(); + ui->gainMode->addItem("automatic"); } ui->gainMode->blockSignals(false); @@ -413,11 +415,20 @@ void BladeRF2MIMOGui::on_spectrumIndex_currentIndexChanged(int index) updateSampleRateAndFrequency(); } -void BladeRF2MIMOGui::on_startStop_toggled(bool checked) +void BladeRF2MIMOGui::on_startStopRx_toggled(bool checked) { if (m_doApplySettings) { - BladeRF2MIMO::MsgStartStop *message = BladeRF2MIMO::MsgStartStop::create(checked, m_rxElseTx); + BladeRF2MIMO::MsgStartStop *message = BladeRF2MIMO::MsgStartStop::create(checked, true); + m_sampleMIMO->getInputMessageQueue()->push(message); + } +} + +void BladeRF2MIMOGui::on_startStopTx_toggled(bool checked) +{ + if (m_doApplySettings) + { + BladeRF2MIMO::MsgStartStop *message = BladeRF2MIMO::MsgStartStop::create(checked, false); m_sampleMIMO->getInputMessageQueue()->push(message); } } @@ -497,7 +508,12 @@ void BladeRF2MIMOGui::on_sampleRate_changed(quint64 value) void BladeRF2MIMOGui::on_fcPos_currentIndexChanged(int index) { - m_settings.m_fcPos = (BladeRF2MIMOSettings::fcPos_t) (index < 0 ? 0 : index > 2 ? 2 : index); + if (m_rxElseTx) { + m_settings.m_fcPosRx = (BladeRF2MIMOSettings::fcPos_t) (index < 0 ? 0 : index > 2 ? 2 : index); + } else { + m_settings.m_fcPosTx = (BladeRF2MIMOSettings::fcPos_t) (index < 0 ? 0 : index > 2 ? 2 : index); + } + displayFcTooltip(); sendSettings(); } @@ -681,21 +697,38 @@ void BladeRF2MIMOGui::updateStatus() { int state = m_deviceUISet->m_deviceAPI->state(); - if(m_lastEngineState != state) + if (m_lastEngineState != state) { switch(state) { case DeviceAPI::StNotStarted: - ui->startStop->setStyleSheet("QToolButton { background:rgb(79,79,79); }"); + ui->startStopRx->setStyleSheet("QToolButton { background:rgb(79,79,79); }"); + ui->startStopTx->setStyleSheet("QToolButton { background:rgb(79,79,79); }"); break; case DeviceAPI::StIdle: - ui->startStop->setStyleSheet("QToolButton { background-color : blue; }"); + ui->startStopRx->setStyleSheet("QToolButton { background-color : blue; }"); + ui->startStopTx->setStyleSheet("QToolButton { background-color : blue; }"); break; case DeviceAPI::StRunning: - ui->startStop->setStyleSheet("QToolButton { background-color : green; }"); + { + if (m_sampleMIMO->getRxRunning()) { + ui->startStopRx->setStyleSheet("QToolButton { background-color : green; }"); + } else { + ui->startStopRx->setStyleSheet("QToolButton { background-color : blue; }"); + } + if (m_sampleMIMO->getTxRunning()) { + ui->startStopTx->setStyleSheet("QToolButton { background-color : green; }"); + } else { + ui->startStopTx->setStyleSheet("QToolButton { background-color : blue; }"); + } + } break; case DeviceAPI::StError: - ui->startStop->setStyleSheet("QToolButton { background-color : red; }"); + if (m_rxElseTx) { + ui->startStopRx->setStyleSheet("QToolButton { background-color : red; }"); + } else { + ui->startStopTx->setStyleSheet("QToolButton { background-color : red; }"); + } QMessageBox::information(this, tr("Message"), m_deviceUISet->m_deviceAPI->errorMessage()); break; default: diff --git a/plugins/samplemimo/bladerf2mimo/bladerf2mimogui.h b/plugins/samplemimo/bladerf2mimo/bladerf2mimogui.h index d5465a895..f699a2958 100644 --- a/plugins/samplemimo/bladerf2mimo/bladerf2mimogui.h +++ b/plugins/samplemimo/bladerf2mimo/bladerf2mimogui.h @@ -100,7 +100,8 @@ private slots: void on_streamIndex_currentIndexChanged(int index); void on_spectrumSide_currentIndexChanged(int index); void on_spectrumIndex_currentIndexChanged(int index); - void on_startStop_toggled(bool checked); + void on_startStopRx_toggled(bool checked); + void on_startStopTx_toggled(bool checked); void on_record_toggled(bool checked); void on_centerFrequency_changed(quint64 value); void on_LOppm_valueChanged(int value); diff --git a/plugins/samplemimo/bladerf2mimo/bladerf2mimogui.ui b/plugins/samplemimo/bladerf2mimo/bladerf2mimogui.ui index 375271bb8..1070922ac 100644 --- a/plugins/samplemimo/bladerf2mimo/bladerf2mimogui.ui +++ b/plugins/samplemimo/bladerf2mimo/bladerf2mimogui.ui @@ -6,7 +6,7 @@ 0 0 - 350 + 366 220 @@ -182,6 +182,57 @@ + + + + Qt::Vertical + + + + + + + Rx + + + + + + + start/stop acquisition (Rx) + + + + + + + :/play.png + :/stop.png:/play.png + + + + + + + Tx + + + + + + + start/stop generation (Tx) + + + + + + + :/play.png + :/stop.png:/play.png + + + @@ -206,21 +257,6 @@ - - - - start/stop acquisition - - - - - - - :/play.png - :/stop.png:/play.png - - - diff --git a/plugins/samplemimo/bladerf2mimo/bladerf2mimosettings.cpp b/plugins/samplemimo/bladerf2mimo/bladerf2mimosettings.cpp index 59902a876..6f53a8bdb 100644 --- a/plugins/samplemimo/bladerf2mimo/bladerf2mimosettings.cpp +++ b/plugins/samplemimo/bladerf2mimo/bladerf2mimosettings.cpp @@ -31,7 +31,7 @@ void BladeRF2MIMOSettings::resetToDefaults() m_rxCenterFrequency = 435000*1000; m_log2Decim = 0; - m_fcPos = FC_POS_INFRA; + m_fcPosRx = FC_POS_INFRA; m_rxBandwidth = 1500000; m_rx0GainMode = 0; m_rx0GlobalGain = 0; @@ -45,6 +45,7 @@ void BladeRF2MIMOSettings::resetToDefaults() m_txCenterFrequency = 435000*1000; m_log2Interp = 0; + m_fcPosTx = FC_POS_CENTER; m_txBandwidth = 1500000; m_tx0GlobalGain = -3; m_tx1GlobalGain = -3; @@ -68,7 +69,7 @@ QByteArray BladeRF2MIMOSettings::serialize() const s.writeU64(10, m_rxCenterFrequency); s.writeU32(11, m_log2Decim); - s.writeS32(12, (int) m_fcPos); + s.writeS32(12, (int) m_fcPosRx); s.writeS32(13, m_rxBandwidth); s.writeS32(14, m_rx0GainMode); s.writeS32(15, m_rx0GlobalGain); @@ -88,6 +89,7 @@ QByteArray BladeRF2MIMOSettings::serialize() const s.writeBool(35, m_txBiasTee); s.writeBool(36, m_txTransverterMode); s.writeS64(37, m_txTransverterDeltaFrequency); + s.writeS32(38, (int) m_fcPosTx); s.writeString(50, m_fileRecordName); s.writeBool(51, m_useReverseAPI); @@ -118,8 +120,8 @@ bool BladeRF2MIMOSettings::deserialize(const QByteArray& data) d.readU64(10, &m_rxCenterFrequency, 435000*1000); d.readU32(11, &m_log2Decim); - d.readS32(12, &intval); - m_fcPos = (fcPos_t) intval; + d.readS32(12, &intval, 0); + m_fcPosRx = (fcPos_t) intval; d.readS32(13, &m_rxBandwidth); d.readS32(14, &m_rx0GainMode); d.readS32(15, &m_rx0GlobalGain); @@ -139,6 +141,8 @@ bool BladeRF2MIMOSettings::deserialize(const QByteArray& data) d.readBool(35, &m_txBiasTee); d.readBool(36, &m_txTransverterMode, false); d.readS64(37, &m_txTransverterDeltaFrequency, 0); + d.readS32(38, &intval, 2); + m_fcPosTx = (fcPos_t) intval; d.readString(50, &m_fileRecordName, ""); d.readBool(51, &m_useReverseAPI, false); diff --git a/plugins/samplemimo/bladerf2mimo/bladerf2mimosettings.h b/plugins/samplemimo/bladerf2mimo/bladerf2mimosettings.h index c89e76a50..aa860bbe3 100644 --- a/plugins/samplemimo/bladerf2mimo/bladerf2mimosettings.h +++ b/plugins/samplemimo/bladerf2mimo/bladerf2mimosettings.h @@ -33,7 +33,7 @@ struct BladeRF2MIMOSettings { quint64 m_rxCenterFrequency; quint32 m_log2Decim; - fcPos_t m_fcPos; + fcPos_t m_fcPosRx; qint32 m_rxBandwidth; int m_rx0GainMode; int m_rx0GlobalGain; @@ -47,6 +47,7 @@ struct BladeRF2MIMOSettings { quint64 m_txCenterFrequency; quint32 m_log2Interp; + fcPos_t m_fcPosTx; qint32 m_txBandwidth; int m_tx0GlobalGain; int m_tx1GlobalGain; diff --git a/plugins/samplemimo/bladerf2mimo/bladerf2mothread.cpp b/plugins/samplemimo/bladerf2mimo/bladerf2mothread.cpp index c2e735ba9..5e5abe3a1 100644 --- a/plugins/samplemimo/bladerf2mimo/bladerf2mothread.cpp +++ b/plugins/samplemimo/bladerf2mimo/bladerf2mothread.cpp @@ -16,7 +16,7 @@ /////////////////////////////////////////////////////////////////////////////////// #include "bladerf2/devicebladerf2shared.h" -#include "dsp/samplesourcefifo.h" +#include "dsp/samplemofifo.h" #include "bladerf2mothread.h" @@ -106,31 +106,30 @@ unsigned int BladeRF2MOThread::getLog2Interpolation() const return m_log2Interp; } -void BladeRF2MOThread::setFifo(unsigned int channel, SampleSourceFifo *sampleFifo) +void BladeRF2MOThread::setFcPos(int fcPos) { - if (channel < 2) { - m_sampleFifo[channel] = sampleFifo; - } + m_fcPos = fcPos; } -SampleSourceFifo *BladeRF2MOThread::getFifo(unsigned int channel) +int BladeRF2MOThread::getFcPos() const { - if (channel < 2) { - return m_sampleFifo[channel]; - } else { - return nullptr; - } + return m_fcPos; } void BladeRF2MOThread::callback(qint16* buf, qint32 samplesPerChannel) { - for (unsigned int channel = 0; channel < 2; channel++) + unsigned int iPart1Begin, iPart1End, iPart2Begin, iPart2End; + m_sampleFifo->readSync(samplesPerChannel, iPart1Begin, iPart1End, iPart2Begin, iPart2End); + + if (iPart1Begin != iPart1End) { - if (m_sampleFifo[channel]) { - channelCallback(&buf[2*samplesPerChannel*channel], samplesPerChannel, channel); - } else { - std::fill(&buf[2*samplesPerChannel*channel], &buf[2*samplesPerChannel*channel]+2*samplesPerChannel, 0); // fill with zero samples - } + callbackPart(buf, samplesPerChannel, iPart1Begin, iPart1End - iPart1Begin); + } + + if (iPart2Begin != iPart2End) + { + unsigned int part1Size = iPart1End - iPart1End; + callbackPart(buf + 2*part1Size, samplesPerChannel, iPart2Begin, iPart2End - iPart2Begin); } int status = bladerf_interleave_stream_buffer(BLADERF_TX_X2, BLADERF_FORMAT_SC16_Q11 , samplesPerChannel*2, (void *) buf); @@ -143,55 +142,96 @@ void BladeRF2MOThread::callback(qint16* buf, qint32 samplesPerChannel) } // Interpolate according to specified log2 (ex: log2=4 => decim=16). len is a number of samples (not a number of I or Q) -void BladeRF2MOThread::channelCallback(qint16* buf, qint32 len, unsigned int channel) +void BladeRF2MOThread::callbackPart(qint16* buf, qint32 samplesPerChannel, int iBegin, qint32 nSamples) { - if (m_sampleFifo[channel]) + for (unsigned int channel = 0; channel < 2; channel++) { - float bal = m_sampleFifo[channel]->getRWBalance(); - - if (bal < -0.25) { - qDebug("BladeRF2MOThread::channelCallback: read lags: %f", bal); - } else if (bal > 0.25) { - qDebug("BladeRF2MOThread::channelCallback: read leads: %f", bal); - } - - SampleVector::iterator beginRead; - m_sampleFifo[channel]->readAdvance(beginRead, len/(1<getData(channel).begin() + iBegin; if (m_log2Interp == 0) { - m_interpolators[channel].interpolate1(&beginRead, buf, len*2); + m_interpolators[channel].interpolate1(&begin, &buf[channel*2*samplesPerChannel], nSamples*2); } else { - switch (m_log2Interp) + if (m_fcPos == 0) // Infra { - case 1: - m_interpolators[channel].interpolate2_cen(&beginRead, buf, len*2); - break; - case 2: - m_interpolators[channel].interpolate4_cen(&beginRead, buf, len*2); - break; - case 3: - m_interpolators[channel].interpolate8_cen(&beginRead, buf, len*2); - break; - case 4: - m_interpolators[channel].interpolate16_cen(&beginRead, buf, len*2); - break; - case 5: - m_interpolators[channel].interpolate32_cen(&beginRead, buf, len*2); - break; - case 6: - m_interpolators[channel].interpolate64_cen(&beginRead, buf, len*2); - break; - default: - break; + switch (m_log2Interp) + { + case 1: + m_interpolators[channel].interpolate2_inf(&begin, &buf[channel*2*samplesPerChannel], nSamples*2); + break; + case 2: + m_interpolators[channel].interpolate4_inf(&begin, &buf[channel*2*samplesPerChannel], nSamples*2); + break; + case 3: + m_interpolators[channel].interpolate8_inf(&begin, &buf[channel*2*samplesPerChannel], nSamples*2); + break; + case 4: + m_interpolators[channel].interpolate16_inf(&begin, &buf[channel*2*samplesPerChannel], nSamples*2); + break; + case 5: + m_interpolators[channel].interpolate32_inf(&begin, &buf[channel*2*samplesPerChannel], nSamples*2); + break; + case 6: + m_interpolators[channel].interpolate64_inf(&begin, &buf[channel*2*samplesPerChannel], nSamples*2); + break; + default: + break; + } + } + else if (m_fcPos == 1) // Supra + { + switch (m_log2Interp) + { + case 1: + m_interpolators[channel].interpolate2_sup(&begin, &buf[channel*2*samplesPerChannel], nSamples*2); + break; + case 2: + m_interpolators[channel].interpolate4_sup(&begin, &buf[channel*2*samplesPerChannel], nSamples*2); + break; + case 3: + m_interpolators[channel].interpolate8_sup(&begin, &buf[channel*2*samplesPerChannel], nSamples*2); + break; + case 4: + m_interpolators[channel].interpolate16_sup(&begin, &buf[channel*2*samplesPerChannel], nSamples*2); + break; + case 5: + m_interpolators[channel].interpolate32_sup(&begin, &buf[channel*2*samplesPerChannel], nSamples*2); + break; + case 6: + m_interpolators[channel].interpolate64_sup(&begin, &buf[channel*2*samplesPerChannel], nSamples*2); + break; + default: + break; + } + } + else if (m_fcPos == 2) // Center + { + switch (m_log2Interp) + { + case 1: + m_interpolators[channel].interpolate2_cen(&begin, &buf[channel*2*samplesPerChannel], nSamples*2); + break; + case 2: + m_interpolators[channel].interpolate4_cen(&begin, &buf[channel*2*samplesPerChannel], nSamples*2); + break; + case 3: + m_interpolators[channel].interpolate8_cen(&begin, &buf[channel*2*samplesPerChannel], nSamples*2); + break; + case 4: + m_interpolators[channel].interpolate16_cen(&begin, &buf[channel*2*samplesPerChannel], nSamples*2); + break; + case 5: + m_interpolators[channel].interpolate32_cen(&begin, &buf[channel*2*samplesPerChannel], nSamples*2); + break; + case 6: + m_interpolators[channel].interpolate64_cen(&begin, &buf[channel*2*samplesPerChannel], nSamples*2); + break; + default: + break; + } } } } - else - { - std::fill(buf, buf+2*len, 0); - } } diff --git a/plugins/samplemimo/bladerf2mimo/bladerf2mothread.h b/plugins/samplemimo/bladerf2mimo/bladerf2mothread.h index d0cf32642..dd81301ad 100644 --- a/plugins/samplemimo/bladerf2mimo/bladerf2mothread.h +++ b/plugins/samplemimo/bladerf2mimo/bladerf2mothread.h @@ -25,7 +25,7 @@ #include "dsp/interpolators.h" -class SampleSourceFifo; +class SampleMOFifo; class BladeRF2MOThread : public QThread { Q_OBJECT @@ -39,8 +39,10 @@ public: bool isRunning() const { return m_running; } void setLog2Interpolation(unsigned int log2_interp); unsigned int getLog2Interpolation() const; - void setFifo(unsigned int channel, SampleSourceFifo *sampleFifo); - SampleSourceFifo *getFifo(unsigned int channel); + void setFcPos(int fcPos); + int getFcPos() const; + void setFifo(SampleMOFifo *sampleFifo) { m_sampleFifo = sampleFifo; } + SampleMOFifo *getFifo() { return m_sampleFifo; } private: QMutex m_startWaitMutex; @@ -49,13 +51,14 @@ private: struct bladerf* m_dev; qint16 *m_buf; //!< Full buffer for SISO or MIMO operation - SampleSourceFifo* m_sampleFifo[2]; + SampleMOFifo* m_sampleFifo; Interpolators m_interpolators[2]; unsigned int m_log2Interp; + int m_fcPos; void run(); unsigned int getNbFifos(); - void channelCallback(qint16* buf, qint32 len, unsigned int channel = 0); + void callbackPart(qint16* buf, qint32 samplesPerChannel, int iBegin, qint32 nSamples); void callback(qint16* buf, qint32 samplesPerChannel); };