Added support for HackRF. Interim state #3

This commit is contained in:
f4exb 2015-09-27 07:37:15 +02:00
parent 3be1a1a3e2
commit 2b092bf660
11 changed files with 221 additions and 324 deletions

View File

@ -71,7 +71,7 @@ The control interface is based on qthid and has been built in the software in th
<h2>HackRF</h2>
HackRF is supported through the libhackrf library that should be installed in your system for proper build of the software and operation support. Add `libhackrf-dev` to the list of dependencies to install.
HackRF is supported through the libhackrf library that should be installed in your system for proper build of the software and operation support. Add `libhackrf-dev` to the list of dependencies to install. Please note that you will need a recent version (2015.07.2 or 2015.07.1 at least) of libhackrf that supports the sequential listing of devices so you might need to build and install the Github version: `https://github.com/mossmann/hackrf.git`. Note also that the firmware must be updated to match the library version as per instructions found in the HackRF wiki.
If you use your own location for libhackrf install directory you need to specify library and include locations. Example with `/opt/install/libhackrf` with the following defines on `cmake` command line:

View File

@ -40,7 +40,6 @@ HackRFGui::HackRFGui(PluginAPI* pluginAPI, QWidget* parent) :
displaySampleRates();
displayBandwidths();
displayImgRejFilters();
connect(m_sampleSource->getOutputMessageQueueToGUI(), SIGNAL(messageEnqueued()), this, SLOT(handleSourceMessages()));
DSPEngine::instance()->setSource(m_sampleSource);
@ -136,7 +135,6 @@ void HackRFGui::displaySettings()
ui->lnaGainText->setText(tr("%1dB").arg(m_settings.m_lnaGain));
ui->lna->setValue(m_settings.m_lnaGain);
ui->rej->setCurrentIndex(m_settings.m_imjRejFilterIndex);
ui->bbFilter->setCurrentIndex(m_settings.m_bandwidthIndex);
ui->vgaText->setText(tr("%1dB").arg(m_settings.m_vgaGain));
@ -151,7 +149,7 @@ void HackRFGui::displaySampleRates()
for (int i = 0; i < HackRFSampleRates::m_nb_rates; i++)
{
ui->sampleRate->addItem(QString("%1M").arg(QString::number(HackRFSampleRates::m_rates[i]/1000.0, 'f', 1)));
ui->sampleRate->addItem(QString("%1M").arg(QString::number(HackRFSampleRates::m_rates_k[i]/1000.0, 'f', 1)));
}
ui->sampleRate->blockSignals(false);
@ -174,7 +172,7 @@ void HackRFGui::displayBandwidths()
for (int i = 0; i < HackRFBandwidths::m_nb_bw; i++)
{
ui->bbFilter->addItem(QString("%1M").arg(QString::number(HackRFBandwidths::m_bw[i]/1000.0, 'f', 2)));
ui->bbFilter->addItem(QString("%1M").arg(QString::number(HackRFBandwidths::m_bw_k[i]/1000.0, 'f', 2)));
}
ui->bbFilter->blockSignals(false);
@ -189,29 +187,6 @@ void HackRFGui::displayBandwidths()
}
}
void HackRFGui::displayImgRejFilters()
{
int savedIndex = m_settings.m_imjRejFilterIndex;
ui->rej->blockSignals(true);
ui->rej->clear();
for (int i = 0; i < HackRFImageRejectFilters::m_nb_rej; i++)
{
ui->rej->addItem(HackRFImageRejectFilters::m_rejName[i]);
}
ui->rej->blockSignals(false);
if (savedIndex < HackRFImageRejectFilters::m_nb_rej)
{
ui->rej->setCurrentIndex(savedIndex);
}
else
{
ui->rej->setCurrentIndex((int) HackRFImageRejectFilters::m_nb_rej-1);
}
}
void HackRFGui::sendSettings()
{
if(!m_updateTimer.isActive())
@ -237,12 +212,6 @@ void HackRFGui::on_sampleRate_currentIndexChanged(int index)
sendSettings();
}
void HackRFGui::on_rej_currentIndexChanged(int index)
{
m_settings.m_imjRejFilterIndex = index;
sendSettings();
}
void HackRFGui::on_bbFilter_currentIndexChanged(int index)
{
m_settings.m_bandwidthIndex = index;
@ -307,22 +276,22 @@ void HackRFGui::on_vga_valueChanged(int value)
void HackRFGui::updateHardware()
{
qDebug() << "AirspyGui::updateHardware";
HackRFInput::MsgConfigureHackRT* message = HackRFInput::MsgConfigureHackRT::create( m_settings);
HackRFInput::MsgConfigureHackRF* message = HackRFInput::MsgConfigureHackRF::create( m_settings);
m_sampleSource->getInputMessageQueue()->push(message);
m_updateTimer.stop();
}
unsigned int HackRFSampleRates::m_rates[] = {2400, 3200, 4800, 6400, 9680, 12800, 19200};
unsigned int HackRFSampleRates::m_rates_k[] = {2400, 3200, 4800, 6400, 9680, 12800, 19200};
unsigned int HackRFSampleRates::getRate(unsigned int rate_index)
{
if (rate_index < m_nb_rates)
{
return m_rates[rate_index];
return m_rates_k[rate_index];
}
else
{
return m_rates[0];
return m_rates_k[0];
}
}
@ -330,7 +299,7 @@ unsigned int HackRFSampleRates::getRateIndex(unsigned int rate)
{
for (unsigned int i=0; i < m_nb_rates; i++)
{
if (rate/1000 == m_rates[i])
if (rate/1000 == m_rates_k[i])
{
return i;
}
@ -339,17 +308,17 @@ unsigned int HackRFSampleRates::getRateIndex(unsigned int rate)
return 0;
}
unsigned int HackRFBandwidths::m_bw[] = {1750, 2500, 3500, 5000, 5500, 6000, 7000, 8000, 9000, 10000, 12000, 14000, 15000, 20000, 24000, 28000};
unsigned int HackRFBandwidths::m_bw_k[] = {1750, 2500, 3500, 5000, 5500, 6000, 7000, 8000, 9000, 10000, 12000, 14000, 15000, 20000, 24000, 28000};
unsigned int HackRFBandwidths::getBandwidth(unsigned int bandwidth_index)
{
if (bandwidth_index < m_nb_bw)
{
return m_bw[bandwidth_index];
return m_bw_k[bandwidth_index];
}
else
{
return m_bw[0];
return m_bw_k[0];
}
}
@ -357,7 +326,7 @@ unsigned int HackRFBandwidths::getBandwidthIndex(unsigned int bandwidth)
{
for (unsigned int i=0; i < m_nb_bw; i++)
{
if (bandwidth == m_bw[i])
if (bandwidth == m_bw_k[i])
{
return i;
}
@ -365,17 +334,3 @@ unsigned int HackRFBandwidths::getBandwidthIndex(unsigned int bandwidth)
return 0;
}
QString HackRFImageRejectFilters::m_rejName[] = {QString("None"), QString("Low"), QString("Hi")};
QString& HackRFImageRejectFilters::getImageRejectFilterName(unsigned int filter_index)
{
if (filter_index < m_nb_rej)
{
return m_rejName[filter_index];
}
else
{
return m_rejName[0];
}
}

View File

@ -66,7 +66,6 @@ private:
void displaySettings();
void displaySampleRates();
void displayBandwidths();
void displayImgRejFilters();
void sendSettings();
private slots:
@ -78,7 +77,6 @@ private slots:
void on_fcPos_currentIndexChanged(int index);
void on_lnaExt_stateChanged(int state);
void on_lna_valueChanged(int value);
void on_rej_currentIndexChanged(int index);
void on_bbFilter_currentIndexChanged(int index);
void on_vga_valueChanged(int value);
void updateHardware();
@ -90,7 +88,7 @@ public:
static unsigned int getRate(unsigned int rate_index);
static unsigned int getRateIndex(unsigned int rate);
static const unsigned int m_nb_rates = 7;
static unsigned int m_rates[m_nb_rates];
static unsigned int m_rates_k[m_nb_rates];
};
class HackRFBandwidths {
@ -98,14 +96,7 @@ public:
static unsigned int getBandwidth(unsigned int bandwidth_index);
static unsigned int getBandwidthIndex(unsigned int bandwidth);
static const unsigned int m_nb_bw = 16;
static unsigned int m_bw[m_nb_bw];
};
class HackRFImageRejectFilters {
public:
static QString& getImageRejectFilterName(unsigned int filter_index);
static const unsigned int m_nb_rej = HackRFGui::HACKRF_IMGREJ_NB;
static QString m_rejName[m_nb_rej];
static unsigned int m_bw_k[m_nb_bw];
};
#endif // INCLUDE_HACKRFGUI_H

View File

@ -270,13 +270,13 @@
<item row="0" column="2">
<widget class="QCheckBox" name="lnaExt">
<property name="toolTip">
<string>Extra LNA</string>
<string>Extra LNA +14dB</string>
</property>
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<property name="text">
<string>LNA Ext</string>
<string>RF Amp</string>
</property>
</widget>
</item>
@ -316,10 +316,16 @@
<string>LNA gain dB</string>
</property>
<property name="maximum">
<number>14</number>
<number>40</number>
</property>
<property name="singleStep">
<number>8</number>
</property>
<property name="pageStep">
<number>1</number>
<number>8</number>
</property>
<property name="value">
<number>16</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -345,30 +351,33 @@
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_rej_bbf">
<layout class="QGridLayout" name="gridLayout_bbf">
<property name="spacing">
<number>3</number>
</property>
<item row="0" column="1">
<widget class="QComboBox" name="rej"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="rejLabel">
<property name="text">
<string>Rej</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="bbFiltLabel">
<property name="text">
<string>BBF</string>
</property>
</widget>
</item>
<item row="0" column="3">
<item row="0" column="1">
<widget class="QComboBox" name="bbFilter"/>
</item>
<item row="0" column="2">
<spacer name="bbSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
@ -389,16 +398,16 @@
<string>VGA gain dB</string>
</property>
<property name="maximum">
<number>15</number>
<number>62</number>
</property>
<property name="singleStep">
<number>1</number>
<number>2</number>
</property>
<property name="pageStep">
<number>1</number>
<number>2</number>
</property>
<property name="value">
<number>5</number>
<number>16</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>

View File

@ -26,7 +26,7 @@
#include "hackrfserializer.h"
#include "hackrfthread.h"
MESSAGE_CLASS_DEFINITION(HackRFInput::MsgConfigureHackRT, Message)
MESSAGE_CLASS_DEFINITION(HackRFInput::MsgConfigureHackRF, Message)
MESSAGE_CLASS_DEFINITION(HackRFInput::MsgReportHackRF, Message)
HackRFInput::Settings::Settings() :
@ -34,7 +34,6 @@ HackRFInput::Settings::Settings() :
m_devSampleRateIndex(0),
m_LOppmTenths(0),
m_lnaGain(14),
m_imjRejFilterIndex(0),
m_bandwidthIndex(0),
m_vgaGain(4),
m_log2Decim(0),
@ -50,7 +49,6 @@ void HackRFInput::Settings::resetToDefaults()
m_devSampleRateIndex = 0;
m_LOppmTenths = 0;
m_lnaGain = 14;
m_imjRejFilterIndex = 0;
m_bandwidthIndex = 0;
m_vgaGain = 4;
m_log2Decim = 0;
@ -69,7 +67,6 @@ QByteArray HackRFInput::Settings::serialize() const
data.m_log2Decim = m_log2Decim;
data.m_fcPos = (qint32) m_fcPos;
data.m_lnaGain = m_lnaGain;
data.m_imjRejFilterIndex = m_imjRejFilterIndex;
data.m_bandwidthIndex = m_bandwidthIndex;
data.m_vgaGain = m_vgaGain;
data.m_biasT = m_biasT;
@ -94,7 +91,6 @@ bool HackRFInput::Settings::deserialize(const QByteArray& serializedData)
m_log2Decim = data.m_log2Decim;
m_fcPos = (fcPos_t) data.m_fcPos;
m_lnaGain = data.m_lnaGain;
m_imjRejFilterIndex = data.m_imjRejFilterIndex;
m_bandwidthIndex = data.m_bandwidthIndex;
m_vgaGain = data.m_vgaGain;
m_biasT = data.m_biasT;
@ -106,11 +102,9 @@ bool HackRFInput::Settings::deserialize(const QByteArray& serializedData)
HackRFInput::HackRFInput() :
m_settings(),
m_dev(0),
m_airspyThread(0),
m_deviceDescription("Airspy")
m_hackRFThread(0),
m_deviceDescription("HackRF")
{
m_sampleRates.push_back(10000000);
m_sampleRates.push_back(2500000);
}
HackRFInput::~HackRFInput()
@ -126,13 +120,13 @@ bool HackRFInput::init(const Message& cmd)
bool HackRFInput::start(int device)
{
QMutexLocker mutexLocker(&m_mutex);
airspy_error rc;
hackrf_error rc;
rc = (airspy_error) airspy_init();
rc = (hackrf_error) hackrf_init();
if (rc != AIRSPY_SUCCESS)
if (rc != HACKRF_SUCCESS)
{
qCritical("AirspyInput::start: failed to initiate Airspy library %s", airspy_error_name(rc));
qCritical("HackRFInput::start: failed to initiate HackRF library %s", hackrf_error_name(rc));
}
if (m_dev != 0)
@ -142,92 +136,54 @@ bool HackRFInput::start(int device)
if (!m_sampleFifo.setSize(1<<19))
{
qCritical("AirspyInput::start: could not allocate SampleFifo");
qCritical("HackRFInput::start: could not allocate SampleFifo");
return false;
}
if ((m_dev = open_airspy_from_sequence(device)) == 0)
if ((m_dev = open_hackrf_from_sequence(device)) == 0)
{
qCritical("AirspyInput::start: could not open Airspy #%d", device);
qCritical("HackRFInput::start: could not open HackRF #%d", device);
return false;
}
#ifdef LIBAIRSPY_DYN_RATES
uint32_t nbSampleRates;
uint32_t *sampleRates;
airspy_get_samplerates(m_dev, &nbSampleRates, 0);
sampleRates = new uint32_t[nbSampleRates];
airspy_get_samplerates(m_dev, sampleRates, nbSampleRates);
if (nbSampleRates == 0)
if((m_hackRFThread = new HackRFThread(m_dev, &m_sampleFifo)) == 0)
{
qCritical("AirspyInput::start: could not obtain Airspy sample rates");
return false;
}
m_sampleRates.clear();
for (int i=0; i<nbSampleRates; i++)
{
m_sampleRates.push_back(sampleRates[i]);
qDebug("AirspyInput::start: sampleRates[%d] = %u Hz", i, sampleRates[i]);
}
delete[] sampleRates;
#endif
MsgReportHackRF *message = MsgReportHackRF::create(m_sampleRates);
getOutputMessageQueueToGUI()->push(message);
rc = (airspy_error) airspy_set_sample_type(m_dev, AIRSPY_SAMPLE_INT16_IQ);
if (rc != AIRSPY_SUCCESS)
{
qCritical("AirspyInput::start: could not set sample type to INT16_IQ");
return false;
}
if((m_airspyThread = new HackRFThread(m_dev, &m_sampleFifo)) == 0)
{
qFatal("AirspyInput::start: out of memory");
qFatal("HackRFInput::start: out of memory");
stop();
return false;
}
m_airspyThread->startWork();
m_hackRFThread->startWork();
mutexLocker.unlock();
applySettings(m_settings, true);
qDebug("AirspyInput::startInput: started");
qDebug("HackRFInput::startInput: started");
return true;
}
void HackRFInput::stop()
{
qDebug("AirspyInput::stop");
qDebug("HackRFInput::stop");
QMutexLocker mutexLocker(&m_mutex);
if(m_airspyThread != 0)
if(m_hackRFThread != 0)
{
m_airspyThread->stopWork();
delete m_airspyThread;
m_airspyThread = 0;
m_hackRFThread->stopWork();
delete m_hackRFThread;
m_hackRFThread = 0;
}
if(m_dev != 0)
{
airspy_stop_rx(m_dev);
airspy_close(m_dev);
hackrf_stop_rx(m_dev);
hackrf_close(m_dev);
m_dev = 0;
}
airspy_exit();
hackrf_exit();
}
const QString& HackRFInput::getDeviceDescription() const
@ -237,7 +193,7 @@ const QString& HackRFInput::getDeviceDescription() const
int HackRFInput::getSampleRate() const
{
int rate = m_sampleRates[m_settings.m_devSampleRateIndex];
int rate = HackRFSampleRates::m_rates_k[m_settings.m_devSampleRateIndex] * 1000;
return (rate / (1<<m_settings.m_log2Decim));
}
@ -248,16 +204,16 @@ quint64 HackRFInput::getCenterFrequency() const
bool HackRFInput::handleMessage(const Message& message)
{
if (MsgConfigureHackRT::match(message))
if (MsgConfigureHackRF::match(message))
{
MsgConfigureHackRT& conf = (MsgConfigureHackRT&) message;
qDebug() << "AirspyInput::handleMessage: MsgConfigureAirspy";
MsgConfigureHackRF& conf = (MsgConfigureHackRF&) message;
qDebug() << "HackRFInput::handleMessage: MsgConfigureHackRF";
bool success = applySettings(conf.getSettings(), false);
if (!success)
{
qDebug("Airspy config error");
qDebug("HackRFInput::handleMessage: config error");
}
return true;
@ -272,15 +228,15 @@ void HackRFInput::setCenterFrequency(quint64 freq_hz)
{
freq_hz += (freq_hz * m_settings.m_LOppmTenths) / 10000000ULL;
airspy_error rc = (airspy_error) airspy_set_freq(m_dev, static_cast<uint32_t>(freq_hz));
hackrf_error rc = (hackrf_error) hackrf_set_freq(m_dev, static_cast<uint64_t>(freq_hz));
if (rc != AIRSPY_SUCCESS)
if (rc != HACKRF_SUCCESS)
{
qWarning("AirspyInput::setCenterFrequency: could not frequency to %llu Hz", freq_hz);
qWarning("HackRFInput::setCenterFrequency: could not frequency to %llu Hz", freq_hz);
}
else
{
qWarning("AirspyInput::setCenterFrequency: frequency set to %llu Hz", freq_hz);
qWarning("HackRFInput::setCenterFrequency: frequency set to %llu Hz", freq_hz);
}
}
@ -289,35 +245,35 @@ bool HackRFInput::applySettings(const Settings& settings, bool force)
QMutexLocker mutexLocker(&m_mutex);
bool forwardChange = false;
airspy_error rc;
hackrf_error rc;
qDebug() << "AirspyInput::applySettings";
qDebug() << "HackRFInput::applySettings";
if ((m_settings.m_devSampleRateIndex != settings.m_devSampleRateIndex) || force)
{
forwardChange = true;
if (settings.m_devSampleRateIndex < m_sampleRates.size())
if (settings.m_devSampleRateIndex < HackRFSampleRates::m_nb_rates)
{
m_settings.m_devSampleRateIndex = settings.m_devSampleRateIndex;
}
else
{
m_settings.m_devSampleRateIndex = m_sampleRates.size() - 1;
m_settings.m_devSampleRateIndex = HackRFSampleRates::m_nb_rates - 1;
}
if (m_dev != 0)
{
rc = (airspy_error) airspy_set_samplerate(m_dev, static_cast<airspy_samplerate_t>(m_settings.m_devSampleRateIndex));
rc = (hackrf_error) hackrf_set_sample_rate_manual(m_dev, HackRFSampleRates::m_rates_k[m_settings.m_devSampleRateIndex]*1000, 1);
if (rc != AIRSPY_SUCCESS)
if (rc != HACKRF_SUCCESS)
{
qCritical("AirspyInput::applySettings: could not set sample rate index %u (%d S/s): %s", m_settings.m_devSampleRateIndex, m_sampleRates[m_settings.m_devSampleRateIndex], airspy_error_name(rc));
qCritical("HackRFInput::applySettings: could not set sample rate index %u (%d kS/s): %s", m_settings.m_devSampleRateIndex, HackRFSampleRates::m_rates_k[m_settings.m_devSampleRateIndex], hackrf_error_name(rc));
}
else
{
qDebug("AirspyInput::applySettings: sample rate set to index: %u (%d S/s)", m_settings.m_devSampleRateIndex, m_sampleRates[m_settings.m_devSampleRateIndex]);
m_airspyThread->setSamplerate(m_sampleRates[m_settings.m_devSampleRateIndex]);
qDebug("HackRFInput::applySettings: sample rate set to index: %u (%d kS/s)", m_settings.m_devSampleRateIndex, HackRFSampleRates::m_rates_k[m_settings.m_devSampleRateIndex]);
m_hackRFThread->setSamplerate(HackRFSampleRates::m_rates_k[m_settings.m_devSampleRateIndex]);
}
}
}
@ -329,8 +285,8 @@ bool HackRFInput::applySettings(const Settings& settings, bool force)
if(m_dev != 0)
{
m_airspyThread->setLog2Decimation(m_settings.m_log2Decim);
qDebug() << "AirspyInput: set decimation to " << (1<<m_settings.m_log2Decim);
m_hackRFThread->setLog2Decimation(m_settings.m_log2Decim);
qDebug() << "HackRFInput: set decimation to " << (1<<m_settings.m_log2Decim);
}
}
@ -340,14 +296,14 @@ bool HackRFInput::applySettings(const Settings& settings, bool force)
if(m_dev != 0)
{
m_airspyThread->setFcPos((int) m_settings.m_fcPos);
qDebug() << "AirspyInput: set fc pos (enum) to " << (int) m_settings.m_fcPos;
m_hackRFThread->setFcPos((int) m_settings.m_fcPos);
qDebug() << "HackRFInput: set fc pos (enum) to " << (int) m_settings.m_fcPos;
}
}
qint64 deviceCenterFrequency = m_settings.m_centerFrequency;
qint64 f_img = deviceCenterFrequency;
quint32 devSampleRate = m_sampleRates[m_settings.m_devSampleRateIndex];
quint32 devSampleRate = HackRFSampleRates::m_rates_k[m_settings.m_devSampleRateIndex] * 1000;
if (force || (m_settings.m_centerFrequency != settings.m_centerFrequency) ||
(m_settings.m_LOppmTenths != settings.m_LOppmTenths))
@ -378,7 +334,7 @@ bool HackRFInput::applySettings(const Settings& settings, bool force)
{
setCenterFrequency(deviceCenterFrequency);
qDebug() << "AirspyInput::applySettings: center freq: " << m_settings.m_centerFrequency << " Hz"
qDebug() << "HackRFInput::applySettings: center freq: " << m_settings.m_centerFrequency << " Hz"
<< " device center freq: " << deviceCenterFrequency << " Hz"
<< " device sample rate: " << devSampleRate << "Hz"
<< " Actual sample rate: " << devSampleRate/(1<<m_settings.m_log2Decim) << "Hz"
@ -394,34 +350,15 @@ bool HackRFInput::applySettings(const Settings& settings, bool force)
if (m_dev != 0)
{
rc = (airspy_error) airspy_set_lna_gain(m_dev, m_settings.m_lnaGain);
rc = (hackrf_error) hackrf_set_lna_gain(m_dev, m_settings.m_lnaGain);
if(rc != AIRSPY_SUCCESS)
if(rc != HACKRF_SUCCESS)
{
qDebug("AirspyInput::applySettings: airspy_set_lna_gain failed: %s", airspy_error_name(rc));
qDebug("HackRFInput::applySettings: airspy_set_lna_gain failed: %s", hackrf_error_name(rc));
}
else
{
qDebug() << "AirspyInput:applySettings: LNA gain set to " << m_settings.m_lnaGain;
}
}
}
if ((m_settings.m_mixerGain != settings.m_mixerGain) || force)
{
m_settings.m_mixerGain = settings.m_mixerGain;
if (m_dev != 0)
{
rc = (airspy_error) airspy_set_mixer_gain(m_dev, m_settings.m_mixerGain);
if(rc != AIRSPY_SUCCESS)
{
qDebug("AirspyInput::applySettings: airspy_set_mixer_gain failed: %s", airspy_error_name(rc));
}
else
{
qDebug() << "AirspyInput:applySettings: mixer gain set to " << m_settings.m_mixerGain;
qDebug() << "HackRFInput:applySettings: LNA gain set to " << m_settings.m_lnaGain;
}
}
}
@ -432,15 +369,43 @@ bool HackRFInput::applySettings(const Settings& settings, bool force)
if (m_dev != 0)
{
rc = (airspy_error) airspy_set_vga_gain(m_dev, m_settings.m_vgaGain);
rc = (hackrf_error) hackrf_set_vga_gain(m_dev, m_settings.m_vgaGain);
if(rc != AIRSPY_SUCCESS)
if (rc != HACKRF_SUCCESS)
{
qDebug("AirspyInput::applySettings: airspy_set_vga_gain failed: %s", airspy_error_name(rc));
qDebug("HackRFInput::applySettings: hackrf_set_vga_gain failed: %s", hackrf_error_name(rc));
}
else
{
qDebug() << "AirspyInput:applySettings: VGA gain set to " << m_settings.m_vgaGain;
qDebug() << "HackRFInput:applySettings: VGA gain set to " << m_settings.m_vgaGain;
}
}
}
if ((m_settings.m_bandwidthIndex != settings.m_bandwidthIndex) || force)
{
if (settings.m_bandwidthIndex < HackRFBandwidths::m_nb_bw)
{
m_settings.m_bandwidthIndex = settings.m_bandwidthIndex;
}
else
{
m_settings.m_bandwidthIndex = HackRFBandwidths::m_nb_bw - 1;
}
if (m_dev != 0)
{
uint32_t bw_index = hackrf_compute_baseband_filter_bw_round_down_lt(HackRFBandwidths::m_bw_k[m_settings.m_bandwidthIndex]);
rc = (hackrf_error) hackrf_set_baseband_filter_bandwidth(m_dev, bw_index);
if (rc != HACKRF_SUCCESS)
{
qDebug("HackRFInput::applySettings: hackrf_set_baseband_filter_bandwidth failed: %s", hackrf_error_name(rc));
}
else
{
qDebug() << "HackRFInput:applySettings: Baseband BW gain set to " << HackRFBandwidths::m_bw_k[m_settings.m_bandwidthIndex];
}
}
}
@ -451,15 +416,15 @@ bool HackRFInput::applySettings(const Settings& settings, bool force)
if (m_dev != 0)
{
rc = (airspy_error) airspy_set_rf_bias(m_dev, (m_settings.m_biasT ? 1 : 0));
rc = (hackrf_error) hackrf_set_antenna_enable(m_dev, (m_settings.m_biasT ? 1 : 0));
if(rc != AIRSPY_SUCCESS)
if(rc != HACKRF_SUCCESS)
{
qDebug("AirspyInput::applySettings: airspy_set_rf_bias failed: %s", airspy_error_name(rc));
qDebug("HackRFInput::applySettings: airspy_set_rf_bias failed: %s", hackrf_error_name(rc));
}
else
{
qDebug() << "AirspyInput:applySettings: bias tee set to " << m_settings.m_biasT;
qDebug() << "HackRFInput:applySettings: bias tee set to " << m_settings.m_biasT;
}
}
}
@ -474,31 +439,20 @@ bool HackRFInput::applySettings(const Settings& settings, bool force)
return true;
}
struct airspy_device *HackRFInput::open_airspy_from_sequence(int sequence)
hackrf_device *HackRFInput::open_hackrf_from_sequence(int sequence)
{
airspy_read_partid_serialno_t read_partid_serialno;
struct airspy_device *devinfo, *retdev = 0;
uint32_t serial_msb = 0;
uint32_t serial_lsb = 0;
airspy_error rc;
int i;
hackrf_device_list_t *hackrf_devices = hackrf_device_list();
hackrf_device *hackrf_ptr;
hackrf_error rc;
for (int i = 0; i < AIRSPY_MAX_DEVICE; i++)
rc = (hackrf_error) hackrf_device_list_open(hackrf_devices, sequence, &hackrf_ptr);
if (rc == HACKRF_SUCCESS)
{
rc = (airspy_error) airspy_open(&devinfo);
if (rc == AIRSPY_SUCCESS)
{
if (i == sequence)
{
return devinfo;
}
}
else
{
break;
}
return hackrf_ptr;
}
else
{
return 0;
}
return 0;
}

View File

@ -18,7 +18,7 @@
#define INCLUDE_HACKRFINPUT_H
#include "dsp/samplesource.h"
#include <libhackrf/hackrf.h>
#include "libhackrf/hackrf.h"
#include <QString>
class HackRFThread;
@ -36,7 +36,6 @@ public:
qint32 m_LOppmTenths;
quint32 m_devSampleRateIndex;
quint32 m_bandwidthIndex;
quint32 m_imjRejFilterIndex;
quint32 m_lnaGain;
quint32 m_vgaGain;
quint32 m_log2Decim;
@ -50,21 +49,21 @@ public:
bool deserialize(const QByteArray& data);
};
class MsgConfigureHackRT : public Message {
class MsgConfigureHackRF : public Message {
MESSAGE_CLASS_DECLARATION
public:
const Settings& getSettings() const { return m_settings; }
static MsgConfigureHackRT* create(const Settings& settings)
static MsgConfigureHackRF* create(const Settings& settings)
{
return new MsgConfigureHackRT(settings);
return new MsgConfigureHackRF(settings);
}
private:
Settings m_settings;
MsgConfigureHackRT(const Settings& settings) :
MsgConfigureHackRF(const Settings& settings) :
Message(),
m_settings(settings)
{ }
@ -74,19 +73,16 @@ public:
MESSAGE_CLASS_DECLARATION
public:
const std::vector<uint32_t>& getSampleRates() const { return m_sampleRates; }
static MsgReportHackRF* create(const std::vector<uint32_t>& sampleRates)
static MsgReportHackRF* create()
{
return new MsgReportHackRF(sampleRates);
return new MsgReportHackRF();
}
protected:
std::vector<uint32_t> m_sampleRates;
MsgReportHackRF(const std::vector<uint32_t>& sampleRates) :
Message(),
m_sampleRates(sampleRates)
MsgReportHackRF() :
Message()
{ }
};
@ -100,21 +96,19 @@ public:
virtual const QString& getDeviceDescription() const;
virtual int getSampleRate() const;
virtual quint64 getCenterFrequency() const;
const std::vector<uint32_t>& getSampleRates() const { return m_sampleRates; }
virtual bool handleMessage(const Message& message);
private:
bool applySettings(const Settings& settings, bool force);
struct airspy_device *open_airspy_from_sequence(int sequence);
hackrf_device *open_hackrf_from_sequence(int sequence);
void setCenterFrequency(quint64 freq);
QMutex m_mutex;
Settings m_settings;
struct airspy_device* m_dev;
HackRFThread* m_airspyThread;
struct hackrf_device* m_dev;
HackRFThread* m_hackRFThread;
QString m_deviceDescription;
std::vector<uint32_t> m_sampleRates;
};
#endif // INCLUDE_HACKRFINPUT_H

View File

@ -16,7 +16,7 @@
#include <QtPlugin>
#include <QAction>
#include <libhackrf/hackrf.h>
#include "libhackrf/hackrf.h"
#include "hackrfplugin.h"
@ -25,7 +25,7 @@
#include "util/simpleserializer.h"
const PluginDescriptor HackRFPlugin::m_pluginDescriptor = {
QString("Airspy Input"),
QString("HackRF Input"),
QString("---"),
QString("(c) Edouard Griffiths, F4EXB"),
QString("https://github.com/f4exb/sdrangel"),
@ -47,70 +47,68 @@ const PluginDescriptor& HackRFPlugin::getPluginDescriptor() const
void HackRFPlugin::initPlugin(PluginAPI* pluginAPI)
{
m_pluginAPI = pluginAPI;
m_pluginAPI->registerSampleSource("org.osmocom.sdr.samplesource.airspy", this);
m_pluginAPI->registerSampleSource("org.osmocom.sdr.samplesource.hackrf", this);
}
PluginInterface::SampleSourceDevices HackRFPlugin::enumSampleSources()
{
SampleSourceDevices result;
airspy_read_partid_serialno_t read_partid_serialno;
struct airspy_device *devinfo;
uint32_t serial_msb = 0;
uint32_t serial_lsb = 0;
airspy_error rc;
hackrf_device_list_t *hackrf_devices = hackrf_device_list();
hackrf_device *hackrf_ptr;
read_partid_serialno_t read_partid_serialno;
hackrf_error rc;
int i;
rc = (airspy_error) airspy_init();
rc = (hackrf_error) hackrf_init();
if (rc != AIRSPY_SUCCESS)
if (rc != HACKRF_SUCCESS)
{
qCritical("AirspyPlugin::enumSampleSources: failed to initiate Airspy library: %s", airspy_error_name(rc));
qCritical("HackRFPlugin::SampleSourceDevices: failed to initiate HackRF library: %s", hackrf_error_name(rc));
}
for (i=0; i < AIRSPY_MAX_DEVICE; i++)
for (i=0; i < hackrf_devices->devicecount; i++)
{
rc = (airspy_error) airspy_open(&devinfo);
rc = (hackrf_error) hackrf_device_list_open(hackrf_devices, i, &hackrf_ptr);
if (rc == AIRSPY_SUCCESS)
if (rc == HACKRF_SUCCESS)
{
qDebug("AirspyPlugin::enumSampleSources: try to enumerate Airspy device #%d", i);
qDebug("HackRFPlugin::enumSampleSources: try to enumerate HackRF device #%d", i);
rc = (airspy_error) airspy_board_partid_serialno_read(devinfo, &read_partid_serialno);
rc = (hackrf_error) hackrf_board_partid_serialno_read(hackrf_ptr, &read_partid_serialno);
if (rc != AIRSPY_SUCCESS)
if (rc != HACKRF_SUCCESS)
{
qDebug("AirspyPlugin::enumSampleSources: failed to read serial no: %s", airspy_error_name(rc));
airspy_close(devinfo);
qDebug("HackRFPlugin::enumSampleSources: failed to read serial no: %s", hackrf_error_name(rc));
hackrf_close(hackrf_ptr);
continue; // next
}
if ((read_partid_serialno.serial_no[2] != serial_msb) && (read_partid_serialno.serial_no[3] != serial_lsb))
{
serial_msb = read_partid_serialno.serial_no[2];
serial_lsb = read_partid_serialno.serial_no[3];
uint32_t serial_msb = read_partid_serialno.serial_no[2];
uint32_t serial_lsb = read_partid_serialno.serial_no[3];
QString serial_str = QString::number(serial_msb, 16) + QString::number(serial_lsb, 16);
uint64_t serial_num = (((uint64_t) serial_msb)<<32) + serial_lsb;
QString displayedName(QString("Airspy #%1 0x%2").arg(i).arg(serial_str));
SimpleSerializer s(1);
s.writeS32(1, i);
s.writeString(2, serial_str);
s.writeU64(3, serial_num);
result.append(SampleSourceDevice(displayedName, "org.osmocom.sdr.samplesource.airspy", s.final()));
qDebug("AirspyPlugin::enumSampleSources: enumerated Airspy device #%d", i);
}
QString serial_str = QString::number(serial_msb, 16) + QString::number(serial_lsb, 16);
uint64_t serial_num = (((uint64_t) serial_msb)<<32) + serial_lsb;
QString displayedName(QString("HackRF #%1 0x%2").arg(i).arg(serial_str));
SimpleSerializer s(1);
s.writeS32(1, i);
s.writeString(2, serial_str);
s.writeU64(3, serial_num);
result.append(SampleSourceDevice(displayedName, "org.osmocom.sdr.samplesource.hackrf", s.final()));
qDebug("HackRFPlugin::enumSampleSources: enumerated HackRF device #%d", i);
airspy_close(devinfo);
hackrf_close(hackrf_ptr);
}
else
{
qDebug("AirspyPlugin::enumSampleSources: enumerated %d Airspy devices %s", i, airspy_error_name(rc));
break; // finished
qDebug("HackRFPlugin::enumSampleSources: failed to enumerate HackRF device #%d: %s", i, hackrf_error_name(rc));
}
}
rc = (airspy_error) airspy_exit();
qDebug("AirspyPlugin::enumSampleSources: airspy_exit: %s", airspy_error_name(rc));
rc = (hackrf_error) hackrf_exit();
qDebug("HackRFPlugin::enumSampleSources: hackrf_exit: %s", hackrf_error_name(rc));
return result;
}
@ -122,7 +120,7 @@ PluginGUI* HackRFPlugin::createSampleSourcePluginGUI(const QString& sourceName,
return 0;
}
if(sourceName == "org.osmocom.sdr.samplesource.airspy")
if(sourceName == "org.osmocom.sdr.samplesource.hackrf")
{
HackRFGui* gui = new HackRFGui(m_pluginAPI);
m_pluginAPI->setInputGUI(gui);

View File

@ -29,11 +29,10 @@ void HackRFSerializer::writeSerializedData(const AirspyData& data, QByteArray& s
s.writeU32(4, data.m_log2Decim);
s.writeS32(5, data.m_fcPos);
s.writeU32(6, data.m_lnaGain);
s.writeU32(7, data.m_imjRejFilterIndex);
s.writeU32(8, data.m_bandwidthIndex);
s.writeU32(9, data.m_vgaGain);
s.writeBool(10, data.m_biasT);
s.writeBool(11, data.m_lnaExt);
s.writeU32(7, data.m_bandwidthIndex);
s.writeU32(8, data.m_vgaGain);
s.writeBool(9, data.m_biasT);
s.writeBool(10, data.m_lnaExt);
serializedData = s.final();
}
@ -61,12 +60,11 @@ bool HackRFSerializer::readSerializedData(const QByteArray& serializedData, Airs
d.readU32(3, &data.m_sampleRateIndex, 0);
d.readU32(4, &data.m_log2Decim, 0);
d.readS32(5, &data.m_fcPos, 0);
d.readU32(6, &data.m_lnaGain, 14);
d.readU32(7, &data.m_imjRejFilterIndex, 0);
d.readU32(8, &data.m_bandwidthIndex, 0);
d.readU32(9, &data.m_vgaGain, 4);
d.readBool(10, &data.m_biasT, false);
d.readBool(11, &data.m_lnaExt, false);
d.readU32(6, &data.m_lnaGain, 16);
d.readU32(7, &data.m_bandwidthIndex, 0);
d.readU32(8, &data.m_vgaGain, 16);
d.readBool(9, &data.m_biasT, false);
d.readBool(10, &data.m_lnaExt, false);
return SampleSourceSerializer::readSerializedData(sampleSourceSerialized, data.m_data);
}
@ -83,10 +81,9 @@ void HackRFSerializer::setDefaults(AirspyData& data)
data.m_sampleRateIndex = 0;
data.m_log2Decim = 0;
data.m_fcPos = 0;
data.m_lnaGain = 14;
data.m_imjRejFilterIndex = 0;
data.m_lnaGain = 16;
data.m_bandwidthIndex = 0;
data.m_vgaGain = 4;
data.m_vgaGain = 16;
data.m_biasT = false;
data.m_lnaExt = false;
}

View File

@ -30,7 +30,6 @@ public:
quint32 m_log2Decim;
qint32 m_fcPos;
quint32 m_lnaGain;
quint32 m_imjRejFilterIndex;
quint32 m_bandwidthIndex;
quint32 m_vgaGain;
bool m_biasT;

View File

@ -22,11 +22,11 @@
HackRFThread *HackRFThread::m_this = 0;
HackRFThread::HackRFThread(struct airspy_device* dev, SampleFifo* sampleFifo, QObject* parent) :
HackRFThread::HackRFThread(hackrf_device* dev, SampleFifo* sampleFifo, QObject* parent) :
QThread(parent),
m_running(false),
m_dev(dev),
m_convertBuffer(AIRSPY_BLOCKSIZE),
m_convertBuffer(HACKRF_BLOCKSIZE),
m_sampleFifo(sampleFifo),
m_samplerate(10),
m_log2Decim(0),
@ -74,41 +74,41 @@ void HackRFThread::setFcPos(int fcPos)
void HackRFThread::run()
{
airspy_error rc;
hackrf_error rc;
m_running = true;
m_startWaiter.wakeAll();
rc = (airspy_error) airspy_start_rx(m_dev, rx_callback, NULL);
rc = (hackrf_error) hackrf_start_rx(m_dev, rx_callback, NULL);
if (rc != AIRSPY_SUCCESS)
if (rc != HACKRF_SUCCESS)
{
qCritical("AirspyInput::run: failed to start Airspy Rx: %s", airspy_error_name(rc));
qCritical("HackRFThread::run: failed to start HackRF Rx: %s", hackrf_error_name(rc));
}
else
{
while ((m_running) && (airspy_is_streaming(m_dev) == AIRSPY_TRUE))
while ((m_running) && (hackrf_is_streaming(m_dev) == HACKRF_TRUE))
{
sleep(1);
}
}
rc = (airspy_error) airspy_stop_rx(m_dev);
rc = (hackrf_error) hackrf_stop_rx(m_dev);
if (rc == AIRSPY_SUCCESS)
if (rc == HACKRF_SUCCESS)
{
qDebug("AirspyInput::run: stopped Airspy Rx");
qDebug("HackRFThread::run: stopped HackRF Rx");
}
else
{
qDebug("AirspyInput::run: failed to stop Airspy Rx: %s", airspy_error_name(rc));
qDebug("HackRFThread::run: failed to stop HackRF Rx: %s", hackrf_error_name(rc));
}
m_running = false;
}
// Decimate according to specified log2 (ex: log2=4 => decim=16)
void HackRFThread::callback(const qint16* buf, qint32 len)
void HackRFThread::callback(const qint8* buf, qint32 len)
{
SampleVector::iterator it = m_convertBuffer.begin();
@ -202,9 +202,9 @@ void HackRFThread::callback(const qint16* buf, qint32 len)
}
int HackRFThread::rx_callback(airspy_transfer_t* transfer)
int HackRFThread::rx_callback(hackrf_transfer* transfer)
{
qint32 bytes_to_write = transfer->sample_count * sizeof(qint16);
m_this->callback((qint16 *) transfer->samples, bytes_to_write);
qint32 bytes_to_write = transfer->valid_length;
m_this->callback((qint8 *) transfer->buffer, bytes_to_write);
return 0;
}

View File

@ -30,7 +30,7 @@ class HackRFThread : public QThread {
Q_OBJECT
public:
HackRFThread(struct airspy_device* dev, SampleFifo* sampleFifo, QObject* parent = NULL);
HackRFThread(hackrf_device* dev, SampleFifo* sampleFifo, QObject* parent = NULL);
~HackRFThread();
void startWork();
@ -44,7 +44,7 @@ private:
QWaitCondition m_startWaiter;
bool m_running;
struct airspy_device* m_dev;
hackrf_device* m_dev;
qint16 m_buf[2*HACKRF_BLOCKSIZE];
SampleVector m_convertBuffer;
SampleFifo* m_sampleFifo;
@ -54,11 +54,11 @@ private:
int m_fcPos;
static HackRFThread *m_this;
Decimators<qint16, SDR_SAMP_SZ, 12> m_decimators;
Decimators<qint8, SDR_SAMP_SZ, 8> m_decimators;
void run();
void callback(const qint16* buf, qint32 len);
static int rx_callback(airspy_transfer_t* transfer);
void callback(const qint8* buf, qint32 len);
static int rx_callback(hackrf_transfer* transfer);
};
#endif // INCLUDE_HACKRFTHREAD_H