mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-12-23 10:05:46 -05:00
HackRF: 2 way Rx/Tx frequency synchronization
This commit is contained in:
parent
64b198e507
commit
9c5c726b97
@ -123,7 +123,9 @@ bool HackRFOutput::start()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_running) stop();
|
||||
if (m_running) {
|
||||
stop();
|
||||
}
|
||||
|
||||
m_hackRFThread = new HackRFOutputThread(m_dev, &m_sampleSourceFifo);
|
||||
|
||||
@ -269,6 +271,32 @@ bool HackRFOutput::handleMessage(const Message& message)
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (DeviceHackRFShared::MsgSynchronizeFrequency::match(message))
|
||||
{
|
||||
DeviceHackRFShared::MsgSynchronizeFrequency& freqMsg = (DeviceHackRFShared::MsgSynchronizeFrequency&) message;
|
||||
qint64 centerFrequency = DeviceSampleSink::calculateCenterFrequency(
|
||||
freqMsg.getFrequency(),
|
||||
0,
|
||||
m_settings.m_log2Interp,
|
||||
DeviceSampleSink::FC_POS_CENTER,
|
||||
m_settings.m_devSampleRate);
|
||||
qDebug("HackRFOutput::handleMessage: MsgSynchronizeFrequency: centerFrequency: %lld Hz", centerFrequency);
|
||||
HackRFOutputSettings settings = m_settings;
|
||||
settings.m_centerFrequency = centerFrequency;
|
||||
|
||||
if (m_guiMessageQueue)
|
||||
{
|
||||
MsgConfigureHackRF* messageToGUI = MsgConfigureHackRF::create(settings, false);
|
||||
m_guiMessageQueue->push(messageToGUI);
|
||||
}
|
||||
|
||||
m_settings.m_centerFrequency = settings.m_centerFrequency;
|
||||
int sampleRate = m_settings.m_devSampleRate/(1<<m_settings.m_log2Interp);
|
||||
DSPSignalNotification *notif = new DSPSignalNotification(sampleRate, m_settings.m_centerFrequency);
|
||||
m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
@ -277,19 +305,18 @@ bool HackRFOutput::handleMessage(const Message& message)
|
||||
|
||||
void HackRFOutput::setDeviceCenterFrequency(quint64 freq_hz, qint32 LOppmTenths)
|
||||
{
|
||||
qint64 df = ((qint64)freq_hz * LOppmTenths) / 10000000LL;
|
||||
freq_hz += df;
|
||||
if (!m_dev) {
|
||||
return;
|
||||
}
|
||||
|
||||
hackrf_error rc = (hackrf_error) hackrf_set_freq(m_dev, static_cast<uint64_t>(freq_hz));
|
||||
qint64 df = ((qint64)freq_hz * LOppmTenths) / 10000000LL;
|
||||
hackrf_error rc = (hackrf_error) hackrf_set_freq(m_dev, static_cast<uint64_t>(freq_hz + df));
|
||||
|
||||
if (rc != HACKRF_SUCCESS)
|
||||
{
|
||||
qWarning("HackRFOutput::setDeviceCenterFrequency: could not frequency to %llu Hz", freq_hz);
|
||||
}
|
||||
else
|
||||
{
|
||||
qWarning("HackRFOutput::setDeviceCenterFrequency: frequency set to %llu Hz", freq_hz);
|
||||
}
|
||||
if (rc != HACKRF_SUCCESS) {
|
||||
qWarning("HackRFOutput::setDeviceCenterFrequency: could not frequency to %llu Hz", freq_hz + df);
|
||||
} else {
|
||||
qDebug("HackRFOutput::setDeviceCenterFrequency: frequency set to %llu Hz", freq_hz + df);
|
||||
}
|
||||
}
|
||||
|
||||
bool HackRFOutput::applySettings(const HackRFOutputSettings& settings, bool force)
|
||||
@ -379,16 +406,8 @@ bool HackRFOutput::applySettings(const HackRFOutputSettings& settings, bool forc
|
||||
}
|
||||
}
|
||||
|
||||
if ((m_settings.m_centerFrequency != settings.m_centerFrequency) || force)
|
||||
{
|
||||
if ((m_settings.m_centerFrequency != settings.m_centerFrequency) || force) {
|
||||
reverseAPIKeys.append("centerFrequency");
|
||||
|
||||
if (m_deviceAPI->getSourceBuddies().size() > 0)
|
||||
{
|
||||
DeviceSourceAPI *buddy = m_deviceAPI->getSourceBuddies()[0];
|
||||
DeviceHackRFShared::MsgSynchronizeFrequency *freqMsg = DeviceHackRFShared::MsgSynchronizeFrequency::create(settings.m_centerFrequency);
|
||||
buddy->getSampleSourceInputMessageQueue()->push(freqMsg);
|
||||
}
|
||||
}
|
||||
if ((m_settings.m_LOppmTenths != settings.m_LOppmTenths) || force) {
|
||||
reverseAPIKeys.append("LOppmTenths");
|
||||
@ -397,11 +416,20 @@ bool HackRFOutput::applySettings(const HackRFOutputSettings& settings, bool forc
|
||||
if (force || (m_settings.m_centerFrequency != settings.m_centerFrequency) ||
|
||||
(m_settings.m_LOppmTenths != settings.m_LOppmTenths))
|
||||
{
|
||||
if (m_dev != 0)
|
||||
{
|
||||
setDeviceCenterFrequency(settings.m_centerFrequency, settings.m_LOppmTenths);
|
||||
qDebug() << "HackRFOutput::applySettings: center freq: " << settings.m_centerFrequency << " Hz LOppm: " << settings.m_LOppmTenths;
|
||||
}
|
||||
qint64 deviceCenterFrequency = DeviceSampleSink::calculateDeviceCenterFrequency(
|
||||
settings.m_centerFrequency,
|
||||
0,
|
||||
settings.m_log2Interp,
|
||||
DeviceSampleSink::FC_POS_CENTER,
|
||||
settings.m_devSampleRate);
|
||||
setDeviceCenterFrequency(deviceCenterFrequency, settings.m_LOppmTenths);
|
||||
|
||||
if (m_deviceAPI->getSourceBuddies().size() > 0)
|
||||
{
|
||||
DeviceSourceAPI *buddy = m_deviceAPI->getSourceBuddies()[0];
|
||||
DeviceHackRFShared::MsgSynchronizeFrequency *freqMsg = DeviceHackRFShared::MsgSynchronizeFrequency::create(deviceCenterFrequency);
|
||||
buddy->getSampleSourceInputMessageQueue()->push(freqMsg);
|
||||
}
|
||||
|
||||
forwardChange = true;
|
||||
}
|
||||
|
@ -142,8 +142,8 @@ private:
|
||||
DeviceHackRFParams m_sharedParams;
|
||||
QNetworkAccessManager *m_networkManager;
|
||||
QNetworkRequest m_networkRequest;
|
||||
|
||||
bool m_running;
|
||||
|
||||
bool openDevice();
|
||||
void closeDevice();
|
||||
bool applySettings(const HackRFOutputSettings& settings, bool force);
|
||||
|
@ -139,7 +139,9 @@ bool HackRFInput::start()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_running) stop();
|
||||
if (m_running) {
|
||||
stop();
|
||||
}
|
||||
|
||||
m_hackRFThread = new HackRFInputThread(m_dev, &m_sampleFifo);
|
||||
|
||||
@ -319,7 +321,20 @@ bool HackRFInput::handleMessage(const Message& message)
|
||||
(DeviceSampleSource::fcPos_t) m_settings.m_fcPos,
|
||||
m_settings.m_devSampleRate);
|
||||
qDebug("HackRFInput::handleMessage: MsgSynchronizeFrequency: centerFrequency: %lld Hz", centerFrequency);
|
||||
setCenterFrequency(centerFrequency);
|
||||
HackRFInputSettings settings = m_settings;
|
||||
settings.m_centerFrequency = centerFrequency;
|
||||
|
||||
if (m_guiMessageQueue)
|
||||
{
|
||||
MsgConfigureHackRF* messageToGUI = MsgConfigureHackRF::create(settings, false);
|
||||
m_guiMessageQueue->push(messageToGUI);
|
||||
}
|
||||
|
||||
m_settings.m_centerFrequency = settings.m_centerFrequency;
|
||||
int sampleRate = m_settings.m_devSampleRate/(1<<m_settings.m_log2Decim);
|
||||
DSPSignalNotification *notif = new DSPSignalNotification(sampleRate, m_settings.m_centerFrequency);
|
||||
m_fileSink->handleMessage(*notif); // forward to file sink
|
||||
m_deviceAPI->getDeviceEngineInputMessageQueue()->push(notif);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -329,20 +344,19 @@ bool HackRFInput::handleMessage(const Message& message)
|
||||
}
|
||||
}
|
||||
|
||||
void HackRFInput::setDeviceCenterFrequency(quint64 freq_hz)
|
||||
void HackRFInput::setDeviceCenterFrequency(quint64 freq_hz, qint32 LOppmTenths)
|
||||
{
|
||||
qint64 df = ((qint64)freq_hz * m_settings.m_LOppmTenths) / 10000000LL;
|
||||
freq_hz += df;
|
||||
if (!m_dev) {
|
||||
return;
|
||||
}
|
||||
|
||||
hackrf_error rc = (hackrf_error) hackrf_set_freq(m_dev, static_cast<uint64_t>(freq_hz));
|
||||
qint64 df = ((qint64)freq_hz * LOppmTenths) / 10000000LL;
|
||||
hackrf_error rc = (hackrf_error) hackrf_set_freq(m_dev, static_cast<uint64_t>(freq_hz + df));
|
||||
|
||||
if (rc != HACKRF_SUCCESS)
|
||||
{
|
||||
qWarning("HackRFInput::setDeviceCenterFrequency: could not frequency to %llu Hz", freq_hz);
|
||||
}
|
||||
else
|
||||
{
|
||||
qWarning("HackRFInput::setDeviceCenterFrequency: frequency set to %llu Hz", freq_hz);
|
||||
if (rc != HACKRF_SUCCESS) {
|
||||
qWarning("HackRFInput::setDeviceCenterFrequency: could not frequency to %llu Hz", freq_hz + df);
|
||||
} else {
|
||||
qDebug("HackRFInput::setDeviceCenterFrequency: frequency set to %llu Hz", freq_hz + df);
|
||||
}
|
||||
}
|
||||
|
||||
@ -405,8 +419,7 @@ bool HackRFInput::applySettings(const HackRFInputSettings& settings, bool force)
|
||||
}
|
||||
}
|
||||
|
||||
if (force || (m_settings.m_centerFrequency != settings.m_centerFrequency)) // forward delta to buddy if necessary
|
||||
{
|
||||
if (force || (m_settings.m_centerFrequency != settings.m_centerFrequency)) {
|
||||
reverseAPIKeys.append("centerFrequency");
|
||||
}
|
||||
|
||||
@ -429,10 +442,14 @@ bool HackRFInput::applySettings(const HackRFInputSettings& settings, bool force)
|
||||
settings.m_log2Decim,
|
||||
(DeviceSampleSource::fcPos_t) settings.m_fcPos,
|
||||
settings.m_devSampleRate);
|
||||
setDeviceCenterFrequency(deviceCenterFrequency, settings.m_LOppmTenths);
|
||||
|
||||
if (m_dev != 0) {
|
||||
setDeviceCenterFrequency(deviceCenterFrequency);
|
||||
}
|
||||
if (m_deviceAPI->getSinkBuddies().size() > 0) // forward to buddy if necessary
|
||||
{
|
||||
DeviceSinkAPI *buddy = m_deviceAPI->getSinkBuddies()[0];
|
||||
DeviceHackRFShared::MsgSynchronizeFrequency *freqMsg = DeviceHackRFShared::MsgSynchronizeFrequency::create(deviceCenterFrequency);
|
||||
buddy->getSampleSinkInputMessageQueue()->push(freqMsg);
|
||||
}
|
||||
|
||||
forwardChange = true;
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ private:
|
||||
bool openDevice();
|
||||
void closeDevice();
|
||||
bool applySettings(const HackRFInputSettings& settings, bool force);
|
||||
void setDeviceCenterFrequency(quint64 freq);
|
||||
void setDeviceCenterFrequency(quint64 freq, qint32 LOppmTenths);
|
||||
void webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& response, const HackRFInputSettings& settings);
|
||||
void webapiReverseSendSettings(QList<QString>& deviceSettingsKeys, const HackRFInputSettings& settings, bool force);
|
||||
void webapiReverseSendStartStop(bool start);
|
||||
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2016 F4EXB //
|
||||
// Copyright (C) 2016-2019 F4EXB //
|
||||
// written by Edouard Griffiths //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
@ -15,6 +15,8 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "dsp/devicesamplesink.h"
|
||||
|
||||
DeviceSampleSink::DeviceSampleSink() :
|
||||
@ -41,6 +43,94 @@ void DeviceSampleSink::handleInputMessages()
|
||||
}
|
||||
}
|
||||
|
||||
qint64 DeviceSampleSink::calculateDeviceCenterFrequency(
|
||||
quint64 centerFrequency,
|
||||
qint64 transverterDeltaFrequency,
|
||||
int log2Interp,
|
||||
fcPos_t fcPos,
|
||||
quint32 devSampleRate,
|
||||
bool transverterMode)
|
||||
{
|
||||
qint64 deviceCenterFrequency = centerFrequency;
|
||||
deviceCenterFrequency -= transverterMode ? transverterDeltaFrequency : 0;
|
||||
deviceCenterFrequency = deviceCenterFrequency < 0 ? 0 : deviceCenterFrequency;
|
||||
qint64 f_img = deviceCenterFrequency;
|
||||
|
||||
deviceCenterFrequency -= calculateFrequencyShift(log2Interp, fcPos, devSampleRate);
|
||||
f_img -= 2*calculateFrequencyShift(log2Interp, fcPos, devSampleRate);
|
||||
|
||||
qDebug() << "DeviceSampleSink::calculateDeviceCenterFrequency:"
|
||||
<< " desired center freq: " << centerFrequency << " Hz"
|
||||
<< " device center freq: " << deviceCenterFrequency << " Hz"
|
||||
<< " device sample rate: " << devSampleRate << "S/s"
|
||||
<< " Actual sample rate: " << devSampleRate/(1<<log2Interp) << "S/s"
|
||||
<< " center freq position code: " << fcPos
|
||||
<< " image frequency: " << f_img << "Hz";
|
||||
|
||||
return deviceCenterFrequency;
|
||||
}
|
||||
|
||||
qint64 DeviceSampleSink::calculateCenterFrequency(
|
||||
quint64 deviceCenterFrequency,
|
||||
qint64 transverterDeltaFrequency,
|
||||
int log2Interp,
|
||||
fcPos_t fcPos,
|
||||
quint32 devSampleRate,
|
||||
bool transverterMode)
|
||||
{
|
||||
qint64 centerFrequency = deviceCenterFrequency;
|
||||
centerFrequency += calculateFrequencyShift(log2Interp, fcPos, devSampleRate);
|
||||
centerFrequency += transverterMode ? transverterDeltaFrequency : 0;
|
||||
centerFrequency = centerFrequency < 0 ? 0 : centerFrequency;
|
||||
|
||||
qDebug() << "DeviceSampleSink::calculateCenterFrequency:"
|
||||
<< " desired center freq: " << centerFrequency << " Hz"
|
||||
<< " device center freq: " << deviceCenterFrequency << " Hz"
|
||||
<< " device sample rate: " << devSampleRate << "S/s"
|
||||
<< " Actual sample rate: " << devSampleRate/(1<<log2Interp) << "S/s"
|
||||
<< " center freq position code: " << fcPos;
|
||||
|
||||
return centerFrequency;
|
||||
}
|
||||
|
||||
/**
|
||||
* log2Interp = 0: no shift
|
||||
*
|
||||
* n = log2Interp <= 2: fc = +/- 1/2^(n-1)
|
||||
* center
|
||||
* | ^ |
|
||||
* | inf | sup |
|
||||
* ^ ^
|
||||
*
|
||||
* n = log2Interp > 2: fc = +/- 1/2^n
|
||||
* center
|
||||
* | ^ |
|
||||
* | |inf| | |sup| |
|
||||
* ^ ^
|
||||
*/
|
||||
qint32 DeviceSampleSink::calculateFrequencyShift(
|
||||
int log2Interp,
|
||||
fcPos_t fcPos,
|
||||
quint32 devSampleRate)
|
||||
{
|
||||
if (log2Interp == 0) { // no shift at all
|
||||
return 0;
|
||||
} else if (log2Interp < 3) {
|
||||
if (fcPos == FC_POS_INFRA) { // shift in the square next to center frequency
|
||||
return -(devSampleRate / (1<<(log2Interp+1)));
|
||||
} else if (fcPos == FC_POS_SUPRA) {
|
||||
return devSampleRate / (1<<(log2Interp+1));
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (fcPos == FC_POS_INFRA) { // shift centered in the square next to center frequency
|
||||
return -(devSampleRate / (1<<(log2Interp)));
|
||||
} else if (fcPos == FC_POS_SUPRA) {
|
||||
return devSampleRate / (1<<(log2Interp));
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2016 F4EXB //
|
||||
// Copyright (C) 2016-2019 F4EXB //
|
||||
// written by Edouard Griffiths //
|
||||
// //
|
||||
// This program is free software; you can redistribute it and/or modify //
|
||||
@ -35,6 +35,12 @@ namespace SWGSDRangel
|
||||
class SDRBASE_API DeviceSampleSink : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
typedef enum {
|
||||
FC_POS_INFRA = 0,
|
||||
FC_POS_SUPRA,
|
||||
FC_POS_CENTER
|
||||
} fcPos_t;
|
||||
|
||||
DeviceSampleSink();
|
||||
virtual ~DeviceSampleSink();
|
||||
virtual void destroy() = 0;
|
||||
@ -108,6 +114,27 @@ public:
|
||||
MessageQueue *getMessageQueueToGUI() { return m_guiMessageQueue; }
|
||||
SampleSourceFifo* getSampleFifo() { return &m_sampleSourceFifo; }
|
||||
|
||||
static qint64 calculateDeviceCenterFrequency(
|
||||
quint64 centerFrequency,
|
||||
qint64 transverterDeltaFrequency,
|
||||
int log2Interp,
|
||||
fcPos_t fcPos,
|
||||
quint32 devSampleRate,
|
||||
bool transverterMode = false);
|
||||
|
||||
static qint64 calculateCenterFrequency(
|
||||
quint64 deviceCenterFrequency,
|
||||
qint64 transverterDeltaFrequency,
|
||||
int log2Interp,
|
||||
fcPos_t fcPos,
|
||||
quint32 devSampleRate,
|
||||
bool transverterMode = false);
|
||||
|
||||
static qint32 calculateFrequencyShift(
|
||||
int log2Interp,
|
||||
fcPos_t fcPos,
|
||||
quint32 devSampleRate);
|
||||
|
||||
protected slots:
|
||||
void handleInputMessages();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user