1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2026-08-14 15:33:34 -04:00

BldeRF2 MIMO and Beam steering plugins enhancements and fixes

This commit is contained in:
f4exb
2019-10-27 18:20:36 +01:00
parent 0a1dec4a23
commit f9d7be11cc
17 changed files with 204 additions and 55 deletions
@@ -72,8 +72,8 @@ BladeRF2MIMO::BladeRF2MIMO(DeviceAPI *deviceAPI) :
}
m_mimoType = MIMOHalfSynchronous;
m_sampleMIFifo.init(2, 96000 * 4);
m_sampleMOFifo.init(2, 96000 * 4);
m_sampleMIFifo.init(2, 4096 * 64);
m_sampleMOFifo.init(2, 4096 * 64);
m_deviceAPI->setNbSourceStreams(2);
m_deviceAPI->setNbSinkStreams(2);
m_networkManager = new QNetworkAccessManager();
@@ -885,26 +885,26 @@ bool BladeRF2MIMO::setRxDeviceCenterFrequency(struct bladerf *dev, quint64 freq_
if (status < 0)
{
qWarning("BladeRF2MIMO::setDeviceCenterFrequency: RX0: bladerf_set_frequency(%lld) failed: %s",
qWarning("BladeRF2MIMO::setRxDeviceCenterFrequency: RX0: bladerf_set_frequency(%lld) failed: %s",
freq_hz, bladerf_strerror(status));
return false;
}
else
{
qDebug("BladeRF2MIMO::setDeviceCenterFrequency: RX0: bladerf_set_frequency(%lld)", freq_hz);
qDebug("BladeRF2MIMO::setRxDeviceCenterFrequency: RX0: bladerf_set_frequency(%lld)", freq_hz);
}
status = bladerf_set_frequency(dev, BLADERF_CHANNEL_RX(1), freq_hz);
if (status < 0)
{
qWarning("BladeRF2MIMO::setDeviceCenterFrequency: RX1: bladerf_set_frequency(%lld) failed: %s",
qWarning("BladeRF2MIMO::setRxDeviceCenterFrequency: RX1: bladerf_set_frequency(%lld) failed: %s",
freq_hz, bladerf_strerror(status));
return false;
}
else
{
qDebug("BladeRF2MIMO::setDeviceCenterFrequency: RX1: bladerf_set_frequency(%lld)", freq_hz);
qDebug("BladeRF2MIMO::setRxDeviceCenterFrequency: RX1: bladerf_set_frequency(%lld)", freq_hz);
}
return true;
@@ -918,28 +918,28 @@ bool BladeRF2MIMO::setTxDeviceCenterFrequency(struct bladerf *dev, quint64 freq_
int status = bladerf_set_frequency(dev, BLADERF_CHANNEL_TX(0), freq_hz);
if (status < 0) {
qWarning("BladeRF2Output::setDeviceCenterFrequency: TX0: bladerf_set_frequency(%lld) failed: %s",
qWarning("BladeRF2Output::setTxDeviceCenterFrequency: TX0: bladerf_set_frequency(%lld) failed: %s",
freq_hz, bladerf_strerror(status));
return false;
}
else
{
qDebug("BladeRF2Output::setDeviceCenterFrequency: TX0: bladerf_set_frequency(%lld)", freq_hz);
return true;
qDebug("BladeRF2Output::setTxDeviceCenterFrequency: TX0: bladerf_set_frequency(%lld)", freq_hz);
}
status = bladerf_set_frequency(dev, BLADERF_CHANNEL_TX(1), freq_hz);
if (status < 0) {
qWarning("BladeRF2Output::setDeviceCenterFrequency: TX1: bladerf_set_frequency(%lld) failed: %s",
qWarning("BladeRF2Output::setTxDeviceCenterFrequency: TX1: bladerf_set_frequency(%lld) failed: %s",
freq_hz, bladerf_strerror(status));
return false;
}
else
{
qDebug("BladeRF2Output::setDeviceCenterFrequency: TX1: bladerf_set_frequency(%lld)", freq_hz);
return true;
qDebug("BladeRF2Output::setTxDeviceCenterFrequency: TX1: bladerf_set_frequency(%lld)", freq_hz);
}
return true;
}
void BladeRF2MIMO::getRxFrequencyRange(uint64_t& min, uint64_t& max, int& step)
@@ -51,6 +51,7 @@ BladeRF2MIMOGui::BladeRF2MIMOGui(DeviceUISet *deviceUISet, QWidget* parent) :
m_streamIndex(0),
m_spectrumRxElseTx(true),
m_spectrumStreamIndex(0),
m_gainLock(false),
m_doApplySettings(true),
m_forceSettings(true),
m_sampleMIMO(nullptr),
@@ -420,6 +421,7 @@ void BladeRF2MIMOGui::on_spectrumSide_currentIndexChanged(int index)
m_spectrumRxElseTx = (index == 0);
m_deviceUISet->m_spectrum->setDisplayedStream(m_spectrumRxElseTx, m_spectrumStreamIndex);
m_deviceUISet->m_deviceAPI->setSpectrumSinkInput(m_spectrumRxElseTx, m_spectrumStreamIndex);
m_deviceUISet->setSpectrumScalingFactor(m_spectrumRxElseTx ? SDR_RX_SCALEF : SDR_TX_SCALEF);
updateSampleRateAndFrequency();
}
@@ -557,6 +559,19 @@ void BladeRF2MIMOGui::on_decim_currentIndexChanged(int index)
sendSettings();
}
void BladeRF2MIMOGui::on_gainLock_toggled(bool checked)
{
if (!m_gainLock && checked)
{
m_settings.m_rx1GlobalGain = m_settings.m_rx0GlobalGain;
m_settings.m_rx1GainMode = m_settings.m_rx0GainMode;
m_settings.m_tx1GlobalGain = m_settings.m_tx0GlobalGain;
sendSettings();
}
m_gainLock = checked;
}
void BladeRF2MIMOGui::on_gainMode_currentIndexChanged(int index)
{
if (!m_rxElseTx) { // not for Tx
@@ -570,7 +585,7 @@ void BladeRF2MIMOGui::on_gainMode_currentIndexChanged(int index)
{
BladeRF2MIMO::GainMode mode = modes[index];
if (m_streamIndex == 0)
if (m_streamIndex == 0 || m_gainLock)
{
if (m_settings.m_rx0GainMode != mode.m_value)
{
@@ -585,7 +600,8 @@ void BladeRF2MIMOGui::on_gainMode_currentIndexChanged(int index)
m_settings.m_rx0GainMode = mode.m_value;
}
else if (m_streamIndex == 1)
if (m_streamIndex == 1 || m_gainLock)
{
if (m_settings.m_rx1GainMode != mode.m_value)
{
@@ -611,17 +627,19 @@ void BladeRF2MIMOGui::on_gain_valueChanged(int value)
if (m_rxElseTx)
{
if (m_streamIndex == 0) {
if (m_streamIndex == 0 || m_gainLock) {
m_settings.m_rx0GlobalGain = value;
} else {
}
if (m_streamIndex == 1 || m_gainLock) {
m_settings.m_rx1GlobalGain = value;
}
}
else
{
if (m_streamIndex == 0) {
if (m_streamIndex == 0 || m_gainLock) {
m_settings.m_tx0GlobalGain = value;
} else {
}
if (m_streamIndex == 1 || m_gainLock) {
m_settings.m_tx1GlobalGain = value;
}
}
@@ -60,6 +60,7 @@ private:
int m_streamIndex; //!< Current stream index being dealt with
bool m_spectrumRxElseTx;
int m_spectrumStreamIndex; //!< Index of the stream displayed on main spectrum
bool m_gainLock; //!< Lock Rx or Tx channel gains (set channel gains to gain of channel 0 when engaged)
QTimer m_updateTimer;
QTimer m_statusTimer;
bool m_doApplySettings;
@@ -113,6 +114,7 @@ private slots:
void on_sampleRate_changed(quint64 value);
void on_fcPos_currentIndexChanged(int index);
void on_decim_currentIndexChanged(int index);
void on_gainLock_toggled(bool checked);
void on_gainMode_currentIndexChanged(int index);
void on_gain_valueChanged(int value);
void on_biasTee_toggled(bool checked);
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>366</width>
<height>220</height>
<height>228</height>
</rect>
</property>
<property name="sizePolicy">
@@ -700,21 +700,24 @@
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_decim" columnstretch="0,0,0,0,0">
<layout class="QGridLayout" name="gridLayout_decim" columnstretch="0,0,0,0,0,0">
<property name="spacing">
<number>3</number>
</property>
<item row="0" column="2">
<item row="0" column="3">
<widget class="QSlider" name="gain">
<property name="toolTip">
<string>Gain value</string>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="1">
<item row="0" column="2">
<widget class="QComboBox" name="gainMode">
<property name="toolTip">
<string>Gain mode</string>
@@ -728,7 +731,7 @@
</property>
</widget>
</item>
<item row="0" column="3">
<item row="0" column="4">
<widget class="QLabel" name="gainText">
<property name="minimumSize">
<size>
@@ -744,7 +747,7 @@
</property>
</widget>
</item>
<item row="0" column="4">
<item row="0" column="5">
<widget class="ButtonSwitch" name="biasTee">
<property name="toolTip">
<string>Bias Tee</string>
@@ -754,6 +757,24 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QToolButton" name="gainLock">
<property name="toolTip">
<string>Lock both channels gain</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../sdrgui/resources/res.qrc">
<normaloff>:/unlocked.png</normaloff>
<normalon>:/locked.png</normalon>:/unlocked.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
@@ -116,7 +116,7 @@ bool BladeRF2MIMOSettings::deserialize(const QByteArray& data)
uint32_t uintval;
d.readS32(1, &m_devSampleRate, 3072000);
d.readS32(2, &m_LOppmTenths);
d.readS32(2, &m_LOppmTenths, 0);
d.readU64(10, &m_rxCenterFrequency, 435000*1000);
d.readU32(11, &m_log2Decim);
@@ -96,9 +96,10 @@ void BladeRF2MOThread::run()
m_running = false;
}
void BladeRF2MOThread::setLog2Interpolation(unsigned int log2_interp)
void BladeRF2MOThread::setLog2Interpolation(unsigned int log2Interp)
{
m_log2Interp = log2_interp;
qDebug("BladeRF2MOThread::setLog2Interpolation: %u", log2Interp);
m_log2Interp = log2Interp;
}
unsigned int BladeRF2MOThread::getLog2Interpolation() const
@@ -123,13 +124,13 @@ void BladeRF2MOThread::callback(qint16* buf, qint32 samplesPerChannel)
if (iPart1Begin != iPart1End)
{
callbackPart(buf, samplesPerChannel, iPart1Begin, iPart1End - iPart1Begin);
callbackPart(buf, (iPart1End - iPart1Begin)*(1<<m_log2Interp), iPart1Begin);
}
if (iPart2Begin != iPart2End)
{
unsigned int part1Size = iPart1End - iPart1End;
callbackPart(buf + 2*part1Size, samplesPerChannel, iPart2Begin, iPart2End - iPart2Begin);
unsigned int shift = (iPart1End - iPart1Begin)*(1<<m_log2Interp);
callbackPart(buf + 2*shift, (iPart2End - iPart2Begin)*(1<<m_log2Interp), iPart2Begin);
}
int status = bladerf_interleave_stream_buffer(BLADERF_TX_X2, BLADERF_FORMAT_SC16_Q11 , samplesPerChannel*2, (void *) buf);
@@ -142,7 +143,7 @@ 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::callbackPart(qint16* buf, qint32 samplesPerChannel, int iBegin, qint32 nSamples)
void BladeRF2MOThread::callbackPart(qint16* buf, qint32 nSamples, int iBegin)
{
for (unsigned int channel = 0; channel < 2; channel++)
{
@@ -150,7 +151,7 @@ void BladeRF2MOThread::callbackPart(qint16* buf, qint32 samplesPerChannel, int i
if (m_log2Interp == 0)
{
m_interpolators[channel].interpolate1(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
m_interpolators[channel].interpolate1(&begin, &buf[channel*2*nSamples], 2*nSamples);
}
else
{
@@ -159,22 +160,22 @@ void BladeRF2MOThread::callbackPart(qint16* buf, qint32 samplesPerChannel, int i
switch (m_log2Interp)
{
case 1:
m_interpolators[channel].interpolate2_inf(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
m_interpolators[channel].interpolate2_inf(&begin, &buf[channel*2*nSamples], 2*nSamples);
break;
case 2:
m_interpolators[channel].interpolate4_inf(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
m_interpolators[channel].interpolate4_inf(&begin, &buf[channel*2*nSamples], 2*nSamples);
break;
case 3:
m_interpolators[channel].interpolate8_inf(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
m_interpolators[channel].interpolate8_inf(&begin, &buf[channel*2*nSamples], 2*nSamples);
break;
case 4:
m_interpolators[channel].interpolate16_inf(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
m_interpolators[channel].interpolate16_inf(&begin, &buf[channel*2*nSamples], 2*nSamples);
break;
case 5:
m_interpolators[channel].interpolate32_inf(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
m_interpolators[channel].interpolate32_inf(&begin, &buf[channel*2*nSamples], 2*nSamples);
break;
case 6:
m_interpolators[channel].interpolate64_inf(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
m_interpolators[channel].interpolate64_inf(&begin, &buf[channel*2*nSamples], 2*nSamples);
break;
default:
break;
@@ -185,22 +186,22 @@ void BladeRF2MOThread::callbackPart(qint16* buf, qint32 samplesPerChannel, int i
switch (m_log2Interp)
{
case 1:
m_interpolators[channel].interpolate2_sup(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
m_interpolators[channel].interpolate2_sup(&begin, &buf[channel*2*nSamples], 2*nSamples);
break;
case 2:
m_interpolators[channel].interpolate4_sup(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
m_interpolators[channel].interpolate4_sup(&begin, &buf[channel*2*nSamples], 2*nSamples);
break;
case 3:
m_interpolators[channel].interpolate8_sup(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
m_interpolators[channel].interpolate8_sup(&begin, &buf[channel*2*nSamples], 2*nSamples);
break;
case 4:
m_interpolators[channel].interpolate16_sup(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
m_interpolators[channel].interpolate16_sup(&begin, &buf[channel*2*nSamples], 2*nSamples);
break;
case 5:
m_interpolators[channel].interpolate32_sup(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
m_interpolators[channel].interpolate32_sup(&begin, &buf[channel*2*nSamples], 2*nSamples);
break;
case 6:
m_interpolators[channel].interpolate64_sup(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
m_interpolators[channel].interpolate64_sup(&begin, &buf[channel*2*nSamples], 2*nSamples);
break;
default:
break;
@@ -211,22 +212,22 @@ void BladeRF2MOThread::callbackPart(qint16* buf, qint32 samplesPerChannel, int i
switch (m_log2Interp)
{
case 1:
m_interpolators[channel].interpolate2_cen(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
m_interpolators[channel].interpolate2_cen(&begin, &buf[channel*2*nSamples], 2*nSamples);
break;
case 2:
m_interpolators[channel].interpolate4_cen(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
m_interpolators[channel].interpolate4_cen(&begin, &buf[channel*2*nSamples], 2*nSamples);
break;
case 3:
m_interpolators[channel].interpolate8_cen(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
m_interpolators[channel].interpolate8_cen(&begin, &buf[channel*2*nSamples], 2*nSamples);
break;
case 4:
m_interpolators[channel].interpolate16_cen(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
m_interpolators[channel].interpolate16_cen(&begin, &buf[channel*2*nSamples], 2*nSamples);
break;
case 5:
m_interpolators[channel].interpolate32_cen(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
m_interpolators[channel].interpolate32_cen(&begin, &buf[channel*2*nSamples], 2*nSamples);
break;
case 6:
m_interpolators[channel].interpolate64_cen(&begin, &buf[channel*2*samplesPerChannel], nSamples*2);
m_interpolators[channel].interpolate64_cen(&begin, &buf[channel*2*nSamples], 2*nSamples);
break;
default:
break;
@@ -37,7 +37,7 @@ public:
void startWork();
void stopWork();
bool isRunning() const { return m_running; }
void setLog2Interpolation(unsigned int log2_interp);
void setLog2Interpolation(unsigned int log2Interp);
unsigned int getLog2Interpolation() const;
void setFcPos(int fcPos);
int getFcPos() const;
@@ -58,7 +58,7 @@ private:
void run();
unsigned int getNbFifos();
void callbackPart(qint16* buf, qint32 samplesPerChannel, int iBegin, qint32 nSamples);
void callbackPart(qint16* buf, qint32 nSamples, int iBegin);
void callback(qint16* buf, qint32 samplesPerChannel);
};