From 64b198e50766f9032f72840b39f889b346295379 Mon Sep 17 00:00:00 2001 From: f4exb Date: Sat, 30 Mar 2019 20:44:55 +0100 Subject: [PATCH] HackRF: suppression of Rx to Tx link frequency. Synchronization of Tx to Rx device center frequency. --- app/main.cpp | 2 +- appbench/main.cpp | 2 +- appsrv/main.cpp | 2 +- debian/changelog | 6 ++ devices/hackrf/devicehackrfshared.cpp | 2 +- devices/hackrf/devicehackrfshared.h | 16 ++-- doc/img/HackRFInput_plugin.png | Bin 27600 -> 26114 bytes doc/img/HackRFInput_plugin.xcf | Bin 107927 -> 107927 bytes .../samplesink/hackrfoutput/hackrfoutput.cpp | 44 +++++---- .../hackrfoutput/hackrfoutputgui.cpp | 9 -- .../hackrfoutput/hackrfoutputplugin.cpp | 2 +- .../samplesource/hackrfinput/hackrfinput.cpp | 42 ++++----- .../hackrfinput/hackrfinputgui.cpp | 6 -- .../samplesource/hackrfinput/hackrfinputgui.h | 1 - .../hackrfinput/hackrfinputgui.ui | 18 +--- .../hackrfinput/hackrfinputplugin.cpp | 2 +- .../hackrfinput/hackrfinputsettings.cpp | 3 - .../hackrfinput/hackrfinputsettings.h | 1 - plugins/samplesource/hackrfinput/readme.md | 22 ++--- sdrbase/dsp/devicesamplesource.cpp | 23 +++++ sdrbase/dsp/devicesamplesource.h | 8 ++ sdrbase/resources/webapi/doc/html2/index.html | 7 +- .../webapi/doc/swagger/include/HackRF.yaml | 2 - .../resources/webapi/doc/swagger/swagger.yaml | 2 +- .../sdrangel/api/swagger/include/HackRF.yaml | 2 - swagger/sdrangel/api/swagger/swagger.yaml | 2 +- swagger/sdrangel/code/html2/index.html | 7 +- .../code/qt5/client/SWGAMDemodReport.cpp | 2 +- .../code/qt5/client/SWGAMDemodReport.h | 2 +- .../code/qt5/client/SWGAMDemodSettings.cpp | 2 +- .../code/qt5/client/SWGAMDemodSettings.h | 2 +- .../code/qt5/client/SWGAMModReport.cpp | 2 +- .../sdrangel/code/qt5/client/SWGAMModReport.h | 2 +- .../code/qt5/client/SWGAMModSettings.cpp | 2 +- .../code/qt5/client/SWGAMModSettings.h | 2 +- .../code/qt5/client/SWGATVModReport.cpp | 2 +- .../code/qt5/client/SWGATVModReport.h | 2 +- .../code/qt5/client/SWGATVModSettings.cpp | 2 +- .../code/qt5/client/SWGATVModSettings.h | 2 +- .../code/qt5/client/SWGAirspyHFReport.cpp | 2 +- .../code/qt5/client/SWGAirspyHFReport.h | 2 +- .../code/qt5/client/SWGAirspyHFSettings.cpp | 2 +- .../code/qt5/client/SWGAirspyHFSettings.h | 2 +- .../code/qt5/client/SWGAirspyReport.cpp | 2 +- .../code/qt5/client/SWGAirspyReport.h | 2 +- .../code/qt5/client/SWGAirspySettings.cpp | 2 +- .../code/qt5/client/SWGAirspySettings.h | 2 +- .../sdrangel/code/qt5/client/SWGArgInfo.cpp | 2 +- swagger/sdrangel/code/qt5/client/SWGArgInfo.h | 2 +- .../sdrangel/code/qt5/client/SWGArgValue.cpp | 2 +- .../sdrangel/code/qt5/client/SWGArgValue.h | 2 +- .../code/qt5/client/SWGAudioDevices.cpp | 2 +- .../code/qt5/client/SWGAudioDevices.h | 2 +- .../code/qt5/client/SWGAudioInputDevice.cpp | 2 +- .../code/qt5/client/SWGAudioInputDevice.h | 2 +- .../code/qt5/client/SWGAudioOutputDevice.cpp | 2 +- .../code/qt5/client/SWGAudioOutputDevice.h | 2 +- .../code/qt5/client/SWGBFMDemodReport.cpp | 2 +- .../code/qt5/client/SWGBFMDemodReport.h | 2 +- .../code/qt5/client/SWGBFMDemodSettings.cpp | 2 +- .../code/qt5/client/SWGBFMDemodSettings.h | 2 +- .../sdrangel/code/qt5/client/SWGBandwidth.cpp | 2 +- .../sdrangel/code/qt5/client/SWGBandwidth.h | 2 +- .../qt5/client/SWGBladeRF1InputSettings.cpp | 2 +- .../qt5/client/SWGBladeRF1InputSettings.h | 2 +- .../qt5/client/SWGBladeRF1OutputSettings.cpp | 2 +- .../qt5/client/SWGBladeRF1OutputSettings.h | 2 +- .../qt5/client/SWGBladeRF2InputReport.cpp | 2 +- .../code/qt5/client/SWGBladeRF2InputReport.h | 2 +- .../qt5/client/SWGBladeRF2InputSettings.cpp | 2 +- .../qt5/client/SWGBladeRF2InputSettings.h | 2 +- .../qt5/client/SWGBladeRF2OutputReport.cpp | 2 +- .../code/qt5/client/SWGBladeRF2OutputReport.h | 2 +- .../qt5/client/SWGBladeRF2OutputSettings.cpp | 2 +- .../qt5/client/SWGBladeRF2OutputSettings.h | 2 +- .../code/qt5/client/SWGCWKeyerSettings.cpp | 2 +- .../code/qt5/client/SWGCWKeyerSettings.h | 2 +- .../sdrangel/code/qt5/client/SWGChannel.cpp | 2 +- swagger/sdrangel/code/qt5/client/SWGChannel.h | 2 +- .../code/qt5/client/SWGChannelListItem.cpp | 2 +- .../code/qt5/client/SWGChannelListItem.h | 2 +- .../code/qt5/client/SWGChannelReport.cpp | 2 +- .../code/qt5/client/SWGChannelReport.h | 2 +- .../code/qt5/client/SWGChannelSettings.cpp | 2 +- .../code/qt5/client/SWGChannelSettings.h | 2 +- .../code/qt5/client/SWGChannelsDetail.cpp | 2 +- .../code/qt5/client/SWGChannelsDetail.h | 2 +- .../sdrangel/code/qt5/client/SWGComplex.cpp | 2 +- swagger/sdrangel/code/qt5/client/SWGComplex.h | 2 +- .../code/qt5/client/SWGDSDDemodReport.cpp | 2 +- .../code/qt5/client/SWGDSDDemodReport.h | 2 +- .../code/qt5/client/SWGDSDDemodSettings.cpp | 2 +- .../code/qt5/client/SWGDSDDemodSettings.h | 2 +- .../code/qt5/client/SWGDVSeralDevices.cpp | 2 +- .../code/qt5/client/SWGDVSeralDevices.h | 2 +- .../code/qt5/client/SWGDVSerialDevice.cpp | 2 +- .../code/qt5/client/SWGDVSerialDevice.h | 2 +- .../code/qt5/client/SWGDeviceListItem.cpp | 2 +- .../code/qt5/client/SWGDeviceListItem.h | 2 +- .../code/qt5/client/SWGDeviceReport.cpp | 2 +- .../code/qt5/client/SWGDeviceReport.h | 2 +- .../sdrangel/code/qt5/client/SWGDeviceSet.cpp | 2 +- .../sdrangel/code/qt5/client/SWGDeviceSet.h | 2 +- .../code/qt5/client/SWGDeviceSetApi.cpp | 2 +- .../code/qt5/client/SWGDeviceSetApi.h | 2 +- .../code/qt5/client/SWGDeviceSetList.cpp | 2 +- .../code/qt5/client/SWGDeviceSetList.h | 2 +- .../code/qt5/client/SWGDeviceSettings.cpp | 2 +- .../code/qt5/client/SWGDeviceSettings.h | 2 +- .../code/qt5/client/SWGDeviceState.cpp | 2 +- .../sdrangel/code/qt5/client/SWGDeviceState.h | 2 +- .../code/qt5/client/SWGErrorResponse.cpp | 2 +- .../code/qt5/client/SWGErrorResponse.h | 2 +- .../code/qt5/client/SWGFCDProPlusSettings.cpp | 2 +- .../code/qt5/client/SWGFCDProPlusSettings.h | 2 +- .../code/qt5/client/SWGFCDProSettings.cpp | 2 +- .../code/qt5/client/SWGFCDProSettings.h | 2 +- .../code/qt5/client/SWGFileSourceReport.cpp | 2 +- .../code/qt5/client/SWGFileSourceReport.h | 2 +- .../code/qt5/client/SWGFileSourceSettings.cpp | 2 +- .../code/qt5/client/SWGFileSourceSettings.h | 2 +- .../code/qt5/client/SWGFreeDVDemodReport.cpp | 2 +- .../code/qt5/client/SWGFreeDVDemodReport.h | 2 +- .../qt5/client/SWGFreeDVDemodSettings.cpp | 2 +- .../code/qt5/client/SWGFreeDVDemodSettings.h | 2 +- .../code/qt5/client/SWGFreeDVModReport.cpp | 2 +- .../code/qt5/client/SWGFreeDVModReport.h | 2 +- .../code/qt5/client/SWGFreeDVModSettings.cpp | 2 +- .../code/qt5/client/SWGFreeDVModSettings.h | 2 +- .../sdrangel/code/qt5/client/SWGFrequency.cpp | 2 +- .../sdrangel/code/qt5/client/SWGFrequency.h | 2 +- .../code/qt5/client/SWGFrequencyBand.cpp | 2 +- .../code/qt5/client/SWGFrequencyBand.h | 2 +- .../code/qt5/client/SWGFrequencyRange.cpp | 2 +- .../code/qt5/client/SWGFrequencyRange.h | 2 +- swagger/sdrangel/code/qt5/client/SWGGain.cpp | 2 +- swagger/sdrangel/code/qt5/client/SWGGain.h | 2 +- .../qt5/client/SWGHackRFInputSettings.cpp | 23 +---- .../code/qt5/client/SWGHackRFInputSettings.h | 8 +- .../qt5/client/SWGHackRFOutputSettings.cpp | 2 +- .../code/qt5/client/SWGHackRFOutputSettings.h | 2 +- .../sdrangel/code/qt5/client/SWGHelpers.cpp | 2 +- swagger/sdrangel/code/qt5/client/SWGHelpers.h | 2 +- .../code/qt5/client/SWGHttpRequest.cpp | 2 +- .../sdrangel/code/qt5/client/SWGHttpRequest.h | 2 +- .../code/qt5/client/SWGInstanceApi.cpp | 2 +- .../sdrangel/code/qt5/client/SWGInstanceApi.h | 2 +- .../client/SWGInstanceChannelsResponse.cpp | 2 +- .../qt5/client/SWGInstanceChannelsResponse.h | 2 +- .../qt5/client/SWGInstanceDevicesResponse.cpp | 2 +- .../qt5/client/SWGInstanceDevicesResponse.h | 2 +- .../qt5/client/SWGInstanceSummaryResponse.cpp | 2 +- .../qt5/client/SWGInstanceSummaryResponse.h | 2 +- .../code/qt5/client/SWGLimeSdrInputReport.cpp | 2 +- .../code/qt5/client/SWGLimeSdrInputReport.h | 2 +- .../qt5/client/SWGLimeSdrInputSettings.cpp | 2 +- .../code/qt5/client/SWGLimeSdrInputSettings.h | 2 +- .../qt5/client/SWGLimeSdrOutputReport.cpp | 2 +- .../code/qt5/client/SWGLimeSdrOutputReport.h | 2 +- .../qt5/client/SWGLimeSdrOutputSettings.cpp | 2 +- .../qt5/client/SWGLimeSdrOutputSettings.h | 2 +- .../qt5/client/SWGLocationInformation.cpp | 2 +- .../code/qt5/client/SWGLocationInformation.h | 2 +- .../code/qt5/client/SWGLoggingInfo.cpp | 2 +- .../sdrangel/code/qt5/client/SWGLoggingInfo.h | 2 +- .../code/qt5/client/SWGModelFactory.h | 2 +- .../code/qt5/client/SWGNFMDemodReport.cpp | 2 +- .../code/qt5/client/SWGNFMDemodReport.h | 2 +- .../code/qt5/client/SWGNFMDemodSettings.cpp | 2 +- .../code/qt5/client/SWGNFMDemodSettings.h | 2 +- .../code/qt5/client/SWGNFMModReport.cpp | 2 +- .../code/qt5/client/SWGNFMModReport.h | 2 +- .../code/qt5/client/SWGNFMModSettings.cpp | 2 +- .../code/qt5/client/SWGNFMModSettings.h | 2 +- .../sdrangel/code/qt5/client/SWGNamedEnum.cpp | 2 +- .../sdrangel/code/qt5/client/SWGNamedEnum.h | 2 +- swagger/sdrangel/code/qt5/client/SWGObject.h | 2 +- .../code/qt5/client/SWGPerseusReport.cpp | 2 +- .../code/qt5/client/SWGPerseusReport.h | 2 +- .../code/qt5/client/SWGPerseusSettings.cpp | 2 +- .../code/qt5/client/SWGPerseusSettings.h | 2 +- .../qt5/client/SWGPlutoSdrInputReport.cpp | 2 +- .../code/qt5/client/SWGPlutoSdrInputReport.h | 2 +- .../qt5/client/SWGPlutoSdrInputSettings.cpp | 2 +- .../qt5/client/SWGPlutoSdrInputSettings.h | 2 +- .../qt5/client/SWGPlutoSdrOutputReport.cpp | 2 +- .../code/qt5/client/SWGPlutoSdrOutputReport.h | 2 +- .../qt5/client/SWGPlutoSdrOutputSettings.cpp | 2 +- .../qt5/client/SWGPlutoSdrOutputSettings.h | 2 +- .../code/qt5/client/SWGPresetExport.cpp | 2 +- .../code/qt5/client/SWGPresetExport.h | 2 +- .../code/qt5/client/SWGPresetGroup.cpp | 2 +- .../sdrangel/code/qt5/client/SWGPresetGroup.h | 2 +- .../code/qt5/client/SWGPresetIdentifier.cpp | 2 +- .../code/qt5/client/SWGPresetIdentifier.h | 2 +- .../code/qt5/client/SWGPresetImport.cpp | 2 +- .../code/qt5/client/SWGPresetImport.h | 2 +- .../code/qt5/client/SWGPresetItem.cpp | 2 +- .../sdrangel/code/qt5/client/SWGPresetItem.h | 2 +- .../code/qt5/client/SWGPresetTransfer.cpp | 2 +- .../code/qt5/client/SWGPresetTransfer.h | 2 +- .../sdrangel/code/qt5/client/SWGPresets.cpp | 2 +- swagger/sdrangel/code/qt5/client/SWGPresets.h | 2 +- .../sdrangel/code/qt5/client/SWGRDSReport.cpp | 2 +- .../sdrangel/code/qt5/client/SWGRDSReport.h | 2 +- .../client/SWGRDSReport_altFrequencies.cpp | 2 +- .../qt5/client/SWGRDSReport_altFrequencies.h | 2 +- swagger/sdrangel/code/qt5/client/SWGRange.cpp | 2 +- swagger/sdrangel/code/qt5/client/SWGRange.h | 2 +- .../code/qt5/client/SWGRangeFloat.cpp | 2 +- .../sdrangel/code/qt5/client/SWGRangeFloat.h | 2 +- .../code/qt5/client/SWGRemoteInputReport.cpp | 2 +- .../code/qt5/client/SWGRemoteInputReport.h | 2 +- .../qt5/client/SWGRemoteInputSettings.cpp | 2 +- .../code/qt5/client/SWGRemoteInputSettings.h | 2 +- .../code/qt5/client/SWGRemoteOutputReport.cpp | 2 +- .../code/qt5/client/SWGRemoteOutputReport.h | 2 +- .../qt5/client/SWGRemoteOutputSettings.cpp | 2 +- .../code/qt5/client/SWGRemoteOutputSettings.h | 2 +- .../code/qt5/client/SWGRemoteSinkSettings.cpp | 2 +- .../code/qt5/client/SWGRemoteSinkSettings.h | 2 +- .../code/qt5/client/SWGRemoteSourceReport.cpp | 2 +- .../code/qt5/client/SWGRemoteSourceReport.h | 2 +- .../qt5/client/SWGRemoteSourceSettings.cpp | 2 +- .../code/qt5/client/SWGRemoteSourceSettings.h | 2 +- .../code/qt5/client/SWGRtlSdrReport.cpp | 2 +- .../code/qt5/client/SWGRtlSdrReport.h | 2 +- .../code/qt5/client/SWGRtlSdrSettings.cpp | 2 +- .../code/qt5/client/SWGRtlSdrSettings.h | 2 +- .../code/qt5/client/SWGSDRPlayReport.cpp | 2 +- .../code/qt5/client/SWGSDRPlayReport.h | 2 +- .../code/qt5/client/SWGSDRPlaySettings.cpp | 2 +- .../code/qt5/client/SWGSDRPlaySettings.h | 2 +- .../code/qt5/client/SWGSSBDemodReport.cpp | 2 +- .../code/qt5/client/SWGSSBDemodReport.h | 2 +- .../code/qt5/client/SWGSSBDemodSettings.cpp | 2 +- .../code/qt5/client/SWGSSBDemodSettings.h | 2 +- .../code/qt5/client/SWGSSBModReport.cpp | 2 +- .../code/qt5/client/SWGSSBModReport.h | 2 +- .../code/qt5/client/SWGSSBModSettings.cpp | 2 +- .../code/qt5/client/SWGSSBModSettings.h | 2 +- .../code/qt5/client/SWGSampleRate.cpp | 2 +- .../sdrangel/code/qt5/client/SWGSampleRate.h | 2 +- .../code/qt5/client/SWGSamplingDevice.cpp | 2 +- .../code/qt5/client/SWGSamplingDevice.h | 2 +- .../client/SWGSoapySDRFrequencySetting.cpp | 2 +- .../qt5/client/SWGSoapySDRFrequencySetting.h | 2 +- .../qt5/client/SWGSoapySDRGainSetting.cpp | 2 +- .../code/qt5/client/SWGSoapySDRGainSetting.h | 2 +- .../qt5/client/SWGSoapySDRInputSettings.cpp | 2 +- .../qt5/client/SWGSoapySDRInputSettings.h | 2 +- .../qt5/client/SWGSoapySDROutputSettings.cpp | 2 +- .../qt5/client/SWGSoapySDROutputSettings.h | 2 +- .../code/qt5/client/SWGSoapySDRReport.cpp | 2 +- .../code/qt5/client/SWGSoapySDRReport.h | 2 +- .../code/qt5/client/SWGSuccessResponse.cpp | 2 +- .../code/qt5/client/SWGSuccessResponse.h | 2 +- .../code/qt5/client/SWGTestSourceSettings.cpp | 2 +- .../code/qt5/client/SWGTestSourceSettings.h | 2 +- .../code/qt5/client/SWGUDPSinkReport.cpp | 2 +- .../code/qt5/client/SWGUDPSinkReport.h | 2 +- .../code/qt5/client/SWGUDPSinkSettings.cpp | 2 +- .../code/qt5/client/SWGUDPSinkSettings.h | 2 +- .../code/qt5/client/SWGUDPSourceReport.cpp | 2 +- .../code/qt5/client/SWGUDPSourceReport.h | 2 +- .../code/qt5/client/SWGUDPSourceSettings.cpp | 2 +- .../code/qt5/client/SWGUDPSourceSettings.h | 2 +- .../code/qt5/client/SWGWFMDemodReport.cpp | 2 +- .../code/qt5/client/SWGWFMDemodReport.h | 2 +- .../code/qt5/client/SWGWFMDemodSettings.cpp | 2 +- .../code/qt5/client/SWGWFMDemodSettings.h | 2 +- .../code/qt5/client/SWGWFMModReport.cpp | 2 +- .../code/qt5/client/SWGWFMModReport.h | 2 +- .../code/qt5/client/SWGWFMModSettings.cpp | 2 +- .../code/qt5/client/SWGWFMModSettings.h | 2 +- .../code/qt5/client/SWGXtrxInputReport.cpp | 2 +- .../code/qt5/client/SWGXtrxInputReport.h | 2 +- .../code/qt5/client/SWGXtrxInputSettings.cpp | 2 +- .../code/qt5/client/SWGXtrxInputSettings.h | 2 +- .../code/qt5/client/SWGXtrxOutputReport.cpp | 2 +- .../code/qt5/client/SWGXtrxOutputReport.h | 2 +- .../code/qt5/client/SWGXtrxOutputSettings.cpp | 2 +- .../code/qt5/client/SWGXtrxOutputSettings.h | 2 +- swagger/sdrangel/examples/ptt_active.py | 85 +++++++++++++++++- 284 files changed, 441 insertions(+), 416 deletions(-) diff --git a/app/main.cpp b/app/main.cpp index 7dd1b8854..43a722cd0 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -35,7 +35,7 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo */ QCoreApplication::setOrganizationName("f4exb"); QCoreApplication::setApplicationName("SDRangel"); - QCoreApplication::setApplicationVersion("4.5.2"); + QCoreApplication::setApplicationVersion("4.5.3"); #if QT_VERSION >= 0x050600 QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); // DPI support QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); //HiDPI pixmaps diff --git a/appbench/main.cpp b/appbench/main.cpp index 357c43735..f4c3e1a97 100644 --- a/appbench/main.cpp +++ b/appbench/main.cpp @@ -57,7 +57,7 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo QCoreApplication::setOrganizationName("f4exb"); QCoreApplication::setApplicationName("SDRangelBench"); - QCoreApplication::setApplicationVersion("4.5.2"); + QCoreApplication::setApplicationVersion("4.5.3"); int catchSignals[] = {SIGQUIT, SIGINT, SIGTERM, SIGHUP}; std::vector vsig(catchSignals, catchSignals + sizeof(catchSignals) / sizeof(int)); diff --git a/appsrv/main.cpp b/appsrv/main.cpp index 5f95a99aa..60833ea8a 100644 --- a/appsrv/main.cpp +++ b/appsrv/main.cpp @@ -56,7 +56,7 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo QCoreApplication::setOrganizationName("f4exb"); QCoreApplication::setApplicationName("SDRangelSrv"); - QCoreApplication::setApplicationVersion("4.5.2"); + QCoreApplication::setApplicationVersion("4.5.3"); int catchSignals[] = {SIGQUIT, SIGINT, SIGTERM, SIGHUP}; std::vector vsig(catchSignals, catchSignals + sizeof(catchSignals) / sizeof(int)); diff --git a/debian/changelog b/debian/changelog index 224400abd..c8b87dcd1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +sdrangel (4.5.3-1) unstable; urgency=medium + + * Fixed HackRF Rx/Tx frequency setting. Fixes issue #318. + + -- Edouard Griffiths, F4EXB Mon, 01 Apr 2019 20:14:18 +0100 + sdrangel (4.5.2-1) unstable; urgency=medium * Send device and channel index in reverse API. Implements issue #312. diff --git a/devices/hackrf/devicehackrfshared.cpp b/devices/hackrf/devicehackrfshared.cpp index c29372074..32907c0c9 100644 --- a/devices/hackrf/devicehackrfshared.cpp +++ b/devices/hackrf/devicehackrfshared.cpp @@ -16,7 +16,7 @@ #include "devicehackrfshared.h" -MESSAGE_CLASS_DEFINITION(DeviceHackRFShared::MsgConfigureFrequencyDelta, Message) +MESSAGE_CLASS_DEFINITION(DeviceHackRFShared::MsgSynchronizeFrequency, Message) const float DeviceHackRFShared::m_sampleFifoLengthInSeconds = 0.25; const int DeviceHackRFShared::m_sampleFifoMinSize = 150000; // 600kS/s knee diff --git a/devices/hackrf/devicehackrfshared.h b/devices/hackrf/devicehackrfshared.h index 6c392b3c2..64d6de7ea 100644 --- a/devices/hackrf/devicehackrfshared.h +++ b/devices/hackrf/devicehackrfshared.h @@ -17,30 +17,32 @@ #ifndef DEVICES_HACKRF_DEVICEHACKRFSHARED_H_ #define DEVICES_HACKRF_DEVICEHACKRFSHARED_H_ +#include + #include "util/message.h" #include "export.h" class DEVICES_API DeviceHackRFShared { public: - class DEVICES_API MsgConfigureFrequencyDelta : public Message + class DEVICES_API MsgSynchronizeFrequency : public Message { MESSAGE_CLASS_DECLARATION public: - int getFrequencyDelta() const { return m_frequencyDelta; } + uint64_t getFrequency() const { return m_frequency; } - static MsgConfigureFrequencyDelta *create(int frequencyDelta) + static MsgSynchronizeFrequency *create(uint64_t frequency) { - return new MsgConfigureFrequencyDelta(frequencyDelta); + return new MsgSynchronizeFrequency(frequency); } private: - int m_frequencyDelta; + uint64_t m_frequency; - MsgConfigureFrequencyDelta(int frequencyDelta) : + MsgSynchronizeFrequency(uint64_t frequency) : Message(), - m_frequencyDelta(frequencyDelta) + m_frequency(frequency) { } }; diff --git a/doc/img/HackRFInput_plugin.png b/doc/img/HackRFInput_plugin.png index 05919e76a96a67a8d7371172c5622b59b61e4966..bac3381496577fc6b9ea7f376d036d8023b951d5 100644 GIT binary patch literal 26114 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 literal 27600 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 delta 40 tcmbP!nr-@Nwhhg>ljChdHeb&@#R_B;Y!)optp^fmR#?1UVKHMl699aB5i|e* diff --git a/plugins/samplesink/hackrfoutput/hackrfoutput.cpp b/plugins/samplesink/hackrfoutput/hackrfoutput.cpp index 52acfcbd1..e90c19b23 100644 --- a/plugins/samplesink/hackrfoutput/hackrfoutput.cpp +++ b/plugins/samplesink/hackrfoutput/hackrfoutput.cpp @@ -246,16 +246,6 @@ bool HackRFOutput::handleMessage(const Message& message) return true; } - else if (DeviceHackRFShared::MsgConfigureFrequencyDelta::match(message)) - { - DeviceHackRFShared::MsgConfigureFrequencyDelta& conf = (DeviceHackRFShared::MsgConfigureFrequencyDelta&) message; - HackRFOutputSettings newSettings = m_settings; - newSettings.m_centerFrequency = m_settings.m_centerFrequency + conf.getFrequencyDelta(); - qDebug() << "HackRFOutput::handleMessage: DeviceHackRFShared::MsgConfigureFrequencyDelta: newFreq: " << newSettings.m_centerFrequency; - applySettings(newSettings, false); - - return true; - } else if (MsgStartStop::match(message)) { MsgStartStop& cmd = (MsgStartStop&) message; @@ -313,18 +303,18 @@ bool HackRFOutput::applySettings(const HackRFOutputSettings& settings, bool forc QList reverseAPIKeys; qDebug() << "HackRFOutput::applySettings" - << " m_centerFrequency: " << m_settings.m_centerFrequency - << " m_LOppmTenths: " << m_settings.m_LOppmTenths - << " m_bandwidth: " << m_settings.m_bandwidth - << " m_devSampleRate: " << m_settings.m_devSampleRate - << " m_log2Interp: " << m_settings.m_log2Interp - << " m_biasT: " << m_settings.m_biasT - << " m_lnaExt: " << m_settings.m_lnaExt - << " m_vgaGain: " << m_settings.m_vgaGain - << " m_useReverseAPI: " << m_settings.m_useReverseAPI - << " m_reverseAPIAddress: " << m_settings.m_reverseAPIAddress - << " m_reverseAPIPort: " << m_settings.m_reverseAPIPort - << " m_reverseAPIDeviceIndex: " << m_settings.m_reverseAPIDeviceIndex + << " m_centerFrequency: " << settings.m_centerFrequency + << " m_LOppmTenths: " << settings.m_LOppmTenths + << " m_bandwidth: " << settings.m_bandwidth + << " m_devSampleRate: " << settings.m_devSampleRate + << " m_log2Interp: " << settings.m_log2Interp + << " m_biasT: " << settings.m_biasT + << " m_lnaExt: " << settings.m_lnaExt + << " m_vgaGain: " << settings.m_vgaGain + << " m_useReverseAPI: " << settings.m_useReverseAPI + << " m_reverseAPIAddress: " << settings.m_reverseAPIAddress + << " m_reverseAPIPort: " << settings.m_reverseAPIPort + << " m_reverseAPIDeviceIndex: " << settings.m_reverseAPIDeviceIndex << " force: " << force; if ((m_settings.m_devSampleRate != settings.m_devSampleRate) || force) { @@ -389,8 +379,16 @@ 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"); diff --git a/plugins/samplesink/hackrfoutput/hackrfoutputgui.cpp b/plugins/samplesink/hackrfoutput/hackrfoutputgui.cpp index 28189e187..d45f3da7d 100644 --- a/plugins/samplesink/hackrfoutput/hackrfoutputgui.cpp +++ b/plugins/samplesink/hackrfoutput/hackrfoutputgui.cpp @@ -181,15 +181,6 @@ void HackRFOutputGui::handleInputMessages() delete message; } - else if (DeviceHackRFShared::MsgConfigureFrequencyDelta::match(*message)) - { - blockApplySettings(true); - DeviceHackRFShared::MsgConfigureFrequencyDelta* deltaMsg = (DeviceHackRFShared::MsgConfigureFrequencyDelta *) message; - ui->centerFrequency->setValue(ui->centerFrequency->getValue() + (deltaMsg->getFrequencyDelta()/1000)); - blockApplySettings(false); - - delete message; - } else { if (handleMessage(*message)) diff --git a/plugins/samplesink/hackrfoutput/hackrfoutputplugin.cpp b/plugins/samplesink/hackrfoutput/hackrfoutputplugin.cpp index 7eff5ca11..935749384 100644 --- a/plugins/samplesink/hackrfoutput/hackrfoutputplugin.cpp +++ b/plugins/samplesink/hackrfoutput/hackrfoutputplugin.cpp @@ -30,7 +30,7 @@ const PluginDescriptor HackRFOutputPlugin::m_pluginDescriptor = { QString("HackRF Output"), - QString("4.5.2"), + QString("4.5.3"), QString("(c) Edouard Griffiths, F4EXB"), QString("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/samplesource/hackrfinput/hackrfinput.cpp b/plugins/samplesource/hackrfinput/hackrfinput.cpp index 8ec0c04ff..d789c620b 100644 --- a/plugins/samplesource/hackrfinput/hackrfinput.cpp +++ b/plugins/samplesource/hackrfinput/hackrfinput.cpp @@ -309,6 +309,20 @@ bool HackRFInput::handleMessage(const Message& message) return true; } + else if (DeviceHackRFShared::MsgSynchronizeFrequency::match(message)) + { + DeviceHackRFShared::MsgSynchronizeFrequency& freqMsg = (DeviceHackRFShared::MsgSynchronizeFrequency&) message; + qint64 centerFrequency = DeviceSampleSource::calculateCenterFrequency( + freqMsg.getFrequency(), + 0, + m_settings.m_log2Decim, + (DeviceSampleSource::fcPos_t) m_settings.m_fcPos, + m_settings.m_devSampleRate); + qDebug("HackRFInput::handleMessage: MsgSynchronizeFrequency: centerFrequency: %lld Hz", centerFrequency); + setCenterFrequency(centerFrequency); + + return true; + } else { return false; @@ -348,9 +362,6 @@ bool HackRFInput::applySettings(const HackRFInputSettings& settings, bool force) if ((m_settings.m_iqCorrection != settings.m_iqCorrection) || force) { reverseAPIKeys.append("iqCorrection"); } - if ((m_settings.m_linkTxFrequency != settings.m_linkTxFrequency) || force) { - reverseAPIKeys.append("linkTxFrequency"); - } if ((m_settings.m_dcBlock != settings.m_dcBlock) || (m_settings.m_iqCorrection != settings.m_iqCorrection) || force) @@ -397,21 +408,6 @@ bool HackRFInput::applySettings(const HackRFInputSettings& settings, bool force) if (force || (m_settings.m_centerFrequency != settings.m_centerFrequency)) // forward delta to buddy if necessary { reverseAPIKeys.append("centerFrequency"); - - if (m_settings.m_linkTxFrequency && (m_deviceAPI->getSinkBuddies().size() > 0)) - { - DeviceSinkAPI *buddy = m_deviceAPI->getSinkBuddies()[0]; - DeviceHackRFShared::MsgConfigureFrequencyDelta *deltaMsg = DeviceHackRFShared::MsgConfigureFrequencyDelta::create( - settings.m_centerFrequency - m_settings.m_centerFrequency); - - if (buddy->getSampleSinkGUIMessageQueue()) - { - DeviceHackRFShared::MsgConfigureFrequencyDelta *deltaMsgToGUI = new DeviceHackRFShared::MsgConfigureFrequencyDelta(*deltaMsg); - buddy->getSampleSinkGUIMessageQueue()->push(deltaMsgToGUI); - } - - buddy->getSampleSinkInputMessageQueue()->push(deltaMsg); - } } if ((m_settings.m_LOppmTenths != settings.m_LOppmTenths) || force) { @@ -561,8 +557,7 @@ bool HackRFInput::applySettings(const HackRFInputSettings& settings, bool force) << " m_devSampleRate: " << m_settings.m_devSampleRate << " m_biasT: " << m_settings.m_biasT << " m_lnaExt: " << m_settings.m_lnaExt - << " m_dcBlock: " << m_settings.m_dcBlock - << " m_linkTxFrequency: " << m_settings.m_linkTxFrequency; + << " m_dcBlock: " << m_settings.m_dcBlock; return true; } @@ -626,9 +621,6 @@ int HackRFInput::webapiSettingsPutPatch( if (deviceSettingsKeys.contains("iqCorrection")) { settings.m_iqCorrection = response.getHackRfInputSettings()->getIqCorrection() != 0; } - if (deviceSettingsKeys.contains("linkTxFrequency")) { - settings.m_linkTxFrequency = response.getHackRfInputSettings()->getLinkTxFrequency() != 0; - } if (deviceSettingsKeys.contains("fileRecordName")) { settings.m_fileRecordName = *response.getHackRfInputSettings()->getFileRecordName(); } @@ -672,7 +664,6 @@ void HackRFInput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& res response.getHackRfInputSettings()->setLnaExt(settings.m_lnaExt ? 1 : 0); response.getHackRfInputSettings()->setDcBlock(settings.m_dcBlock ? 1 : 0); response.getHackRfInputSettings()->setIqCorrection(settings.m_iqCorrection ? 1 : 0); - response.getHackRfInputSettings()->setLinkTxFrequency(settings.m_linkTxFrequency ? 1 : 0); if (response.getHackRfInputSettings()->getFileRecordName()) { *response.getHackRfInputSettings()->getFileRecordName() = settings.m_fileRecordName; @@ -767,9 +758,6 @@ void HackRFInput::webapiReverseSendSettings(QList& deviceSettingsKeys, if (deviceSettingsKeys.contains("iqCorrection") || force) { swgHackRFInputSettings->setIqCorrection(settings.m_iqCorrection ? 1 : 0); } - if (deviceSettingsKeys.contains("linkTxFrequency") || force) { - swgHackRFInputSettings->setLinkTxFrequency(settings.m_linkTxFrequency ? 1 : 0); - } if (deviceSettingsKeys.contains("fileRecordName") || force) { swgHackRFInputSettings->setFileRecordName(new QString(settings.m_fileRecordName)); } diff --git a/plugins/samplesource/hackrfinput/hackrfinputgui.cpp b/plugins/samplesource/hackrfinput/hackrfinputgui.cpp index 6ef9b54ed..94dda70e7 100644 --- a/plugins/samplesource/hackrfinput/hackrfinputgui.cpp +++ b/plugins/samplesource/hackrfinput/hackrfinputgui.cpp @@ -276,12 +276,6 @@ void HackRFInputGui::on_iqImbalance_toggled(bool checked) sendSettings(); } -void HackRFInputGui::on_linkTxFreq_toggled(bool checked) -{ - m_settings.m_linkTxFrequency = checked; - sendSettings(); -} - void HackRFInputGui::on_bbFilter_currentIndexChanged(int index) { int newBandwidth = HackRFBandwidths::getBandwidth(index); diff --git a/plugins/samplesource/hackrfinput/hackrfinputgui.h b/plugins/samplesource/hackrfinput/hackrfinputgui.h index 5e28a879d..635d06dcf 100644 --- a/plugins/samplesource/hackrfinput/hackrfinputgui.h +++ b/plugins/samplesource/hackrfinput/hackrfinputgui.h @@ -88,7 +88,6 @@ private slots: void on_LOppm_valueChanged(int value); void on_dcOffset_toggled(bool checked); void on_iqImbalance_toggled(bool checked); - void on_linkTxFreq_toggled(bool checked); void on_biasT_stateChanged(int state); void on_decim_currentIndexChanged(int index); void on_fcPos_currentIndexChanged(int index); diff --git a/plugins/samplesource/hackrfinput/hackrfinputgui.ui b/plugins/samplesource/hackrfinput/hackrfinputgui.ui index 7a075d010..87c0524c3 100644 --- a/plugins/samplesource/hackrfinput/hackrfinputgui.ui +++ b/plugins/samplesource/hackrfinput/hackrfinputgui.ui @@ -253,7 +253,7 @@ - + Activate antenna bias tee @@ -266,7 +266,7 @@ - + Extra LNA +14dB @@ -292,20 +292,6 @@ - - - - Toggle Tx frequency link - - - ... - - - - :/link.png:/link.png - - - diff --git a/plugins/samplesource/hackrfinput/hackrfinputplugin.cpp b/plugins/samplesource/hackrfinput/hackrfinputplugin.cpp index d937ea180..c986c8f58 100644 --- a/plugins/samplesource/hackrfinput/hackrfinputplugin.cpp +++ b/plugins/samplesource/hackrfinput/hackrfinputplugin.cpp @@ -32,7 +32,7 @@ const PluginDescriptor HackRFInputPlugin::m_pluginDescriptor = { QString("HackRF Input"), - QString("4.5.2"), + QString("4.5.3"), QString("(c) Edouard Griffiths, F4EXB"), QString("https://github.com/f4exb/sdrangel"), true, diff --git a/plugins/samplesource/hackrfinput/hackrfinputsettings.cpp b/plugins/samplesource/hackrfinput/hackrfinputsettings.cpp index 0809b776d..e816b8ccd 100644 --- a/plugins/samplesource/hackrfinput/hackrfinputsettings.cpp +++ b/plugins/samplesource/hackrfinput/hackrfinputsettings.cpp @@ -39,7 +39,6 @@ void HackRFInputSettings::resetToDefaults() m_dcBlock = false; m_iqCorrection = false; m_devSampleRate = 2400000; - m_linkTxFrequency = false; m_fileRecordName = ""; m_useReverseAPI = false; m_reverseAPIAddress = "127.0.0.1"; @@ -62,7 +61,6 @@ QByteArray HackRFInputSettings::serialize() const s.writeBool(10, m_dcBlock); s.writeBool(11, m_iqCorrection); s.writeU64(12, m_devSampleRate); - s.writeBool(13, m_linkTxFrequency); s.writeBool(14, m_useReverseAPI); s.writeString(15, m_reverseAPIAddress); s.writeU32(16, m_reverseAPIPort); @@ -98,7 +96,6 @@ bool HackRFInputSettings::deserialize(const QByteArray& data) d.readBool(10, &m_dcBlock, false); d.readBool(11, &m_iqCorrection, false); d.readU64(12, &m_devSampleRate, 2400000U); - d.readBool(13, &m_linkTxFrequency, false); d.readBool(14, &m_useReverseAPI, false); d.readString(15, &m_reverseAPIAddress, "127.0.0.1"); d.readU32(16, &uintval, 0); diff --git a/plugins/samplesource/hackrfinput/hackrfinputsettings.h b/plugins/samplesource/hackrfinput/hackrfinputsettings.h index b1042ce07..0b8ce554a 100644 --- a/plugins/samplesource/hackrfinput/hackrfinputsettings.h +++ b/plugins/samplesource/hackrfinput/hackrfinputsettings.h @@ -39,7 +39,6 @@ struct HackRFInputSettings { bool m_lnaExt; bool m_dcBlock; bool m_iqCorrection; - bool m_linkTxFrequency; QString m_fileRecordName; bool m_useReverseAPI; QString m_reverseAPIAddress; diff --git a/plugins/samplesource/hackrfinput/readme.md b/plugins/samplesource/hackrfinput/readme.md index cfff23462..e5d384388 100644 --- a/plugins/samplesource/hackrfinput/readme.md +++ b/plugins/samplesource/hackrfinput/readme.md @@ -24,12 +24,12 @@ This is the center frequency of reception in kHz.

1.2: Start/Stop

-Device start / stop button. +Device start / stop button. - Blue triangle icon: device is ready and can be started - Green square icon: device is running and can be stopped - Red square icon: an error occurred. In the case the device was accidentally disconnected you may click on the icon, plug back in and start again. - + If you have the Tx open in another tab and it is running then it will be stopped automatically before the Rx starts. In a similar manner the Rx will be stopped before the Tx is started from the Tx tab. The settings on Rx or Tx tab are reapplied on start so these settings can be considered independent. @@ -40,7 +40,7 @@ Record baseband I/Q stream toggle button

1.4: Baseband sample rate

-Baseband I/Q sample rate in kS/s. This is the device sample rate (4) divided by the decimation factor (6). +Baseband I/Q sample rate in kS/s. This is the device sample rate (4) divided by the decimation factor (6).

2: Local Oscillator correction

@@ -53,21 +53,13 @@ These buttons control the local DSP auto correction options: - **DC**: auto remove DC component - **IQ**: auto make I/Q balance. The DC correction must be enabled for this to be effective. -

3A: Link Tx frequency

- -Use this button to toggle the device Tx frequency link. - -When active (button lit) and a tab is opened for the Tx part of the same device this option will activate the link of the Tx frequency to the Rx frequency. Thus when changing the Rx frequency the Tx frequency will vary by the same amount. This facilitates the split operation or repeater operation. You can also set the Tx frequency so that it follows exactly the Rx frequency (simplex). - -The amount of shift is simply set by changing the frequency in the Tx tab. -

4: Bias tee

Use this checkbox to toggle the +5V power supply on the antenna connector.

5:RF amp

-Use this checkbox to toggle the extra low noise amplifier (LNA). This gives an additional gain of 14 dB. +Use this checkbox to toggle the extra low noise amplifier (LNA). This gives an additional gain of 14 dB.

6: Device sample rate

@@ -89,10 +81,10 @@ The device stream from the HackRF is decimated to obtain the baseband stream. Po

8: Baseband center frequency position relative the the HackRF Rx center frequency

- **Cen**: the decimation operation takes place around the HackRF Rx center frequency Fs - - **Inf**: the decimation operation takes place around Fs - Fc. + - **Inf**: the decimation operation takes place around Fs - Fc. - **Sup**: the decimation operation takes place around Fs + Fc. - -With SR as the sample rate before decimation Fc is calculated as: + +With SR as the sample rate before decimation Fc is calculated as: - if decimation n is 4 or lower: Fc = SR/2^(log2(n)-1). The device center frequency is on the side of the baseband. You need a RF filter bandwidth at least twice the baseband. - if decimation n is 8 or higher: Fc = SR/n. The device center frequency is half the baseband away from the side of the baseband. You need a RF filter bandwidth at least 3 times the baseband. diff --git a/sdrbase/dsp/devicesamplesource.cpp b/sdrbase/dsp/devicesamplesource.cpp index 1a637bc0b..69ec6ebec 100644 --- a/sdrbase/dsp/devicesamplesource.cpp +++ b/sdrbase/dsp/devicesamplesource.cpp @@ -68,6 +68,29 @@ qint64 DeviceSampleSource::calculateDeviceCenterFrequency( return deviceCenterFrequency; } +qint64 DeviceSampleSource::calculateCenterFrequency( + quint64 deviceCenterFrequency, + qint64 transverterDeltaFrequency, + int log2Decim, + fcPos_t fcPos, + quint32 devSampleRate, + bool transverterMode) +{ + qint64 centerFrequency = deviceCenterFrequency; + centerFrequency += calculateFrequencyShift(log2Decim, fcPos, devSampleRate); + centerFrequency += transverterMode ? transverterDeltaFrequency : 0; + centerFrequency = centerFrequency < 0 ? 0 : centerFrequency; + + qDebug() << "DeviceSampleSource::calculateCenterFrequency:" + << " desired center freq: " << centerFrequency << " Hz" + << " device center freq: " << deviceCenterFrequency << " Hz" + << " device sample rate: " << devSampleRate << "S/s" + << " Actual sample rate: " << devSampleRate/(1<

API and SDK Documentation

-
Version: 4.5.2
+
Version: 4.5.3

This is the web REST/JSON API of SDRangel SDR software. SDRangel is an Open Source Qt5/OpenGL 3.0+ (4.3+ in Windows) GUI and server Software Defined Radio and signal analyzer in software. It supports Airspy, BladeRF, HackRF, LimeSDR, PlutoSDR, RTL-SDR, SDRplay RSP1 and FunCube


@@ -24652,7 +24649,7 @@ except ApiException as e:
- Generated 2019-03-25T14:39:14.782+01:00 + Generated 2019-03-30T20:33:10.840+01:00
diff --git a/sdrbase/resources/webapi/doc/swagger/include/HackRF.yaml b/sdrbase/resources/webapi/doc/swagger/include/HackRF.yaml index fd8ce9084..3c1028a0c 100644 --- a/sdrbase/resources/webapi/doc/swagger/include/HackRF.yaml +++ b/sdrbase/resources/webapi/doc/swagger/include/HackRF.yaml @@ -27,8 +27,6 @@ HackRFInputSettings: type: integer iqCorrection: type: integer - linkTxFrequency: - type: integer fileRecordName: type: string useReverseAPI: diff --git a/sdrbase/resources/webapi/doc/swagger/swagger.yaml b/sdrbase/resources/webapi/doc/swagger/swagger.yaml index 01ce9bc71..6655f331d 100644 --- a/sdrbase/resources/webapi/doc/swagger/swagger.yaml +++ b/sdrbase/resources/webapi/doc/swagger/swagger.yaml @@ -15,7 +15,7 @@ info: --- - version: "4.5.2" + version: "4.5.3" title: SDRangel contact: url: "https://github.com/f4exb/sdrangel" diff --git a/swagger/sdrangel/api/swagger/include/HackRF.yaml b/swagger/sdrangel/api/swagger/include/HackRF.yaml index fd8ce9084..3c1028a0c 100644 --- a/swagger/sdrangel/api/swagger/include/HackRF.yaml +++ b/swagger/sdrangel/api/swagger/include/HackRF.yaml @@ -27,8 +27,6 @@ HackRFInputSettings: type: integer iqCorrection: type: integer - linkTxFrequency: - type: integer fileRecordName: type: string useReverseAPI: diff --git a/swagger/sdrangel/api/swagger/swagger.yaml b/swagger/sdrangel/api/swagger/swagger.yaml index 9486e055a..d25c096f1 100644 --- a/swagger/sdrangel/api/swagger/swagger.yaml +++ b/swagger/sdrangel/api/swagger/swagger.yaml @@ -15,7 +15,7 @@ info: --- - version: "4.5.2" + version: "4.5.3" title: SDRangel contact: url: "https://github.com/f4exb/sdrangel" diff --git a/swagger/sdrangel/code/html2/index.html b/swagger/sdrangel/code/html2/index.html index 1eb36808a..eabea493f 100644 --- a/swagger/sdrangel/code/html2/index.html +++ b/swagger/sdrangel/code/html2/index.html @@ -2791,9 +2791,6 @@ margin-bottom: 20px; "iqCorrection" : { "type" : "integer" }, - "linkTxFrequency" : { - "type" : "integer" - }, "fileRecordName" : { "type" : "string" }, @@ -5678,7 +5675,7 @@ margin-bottom: 20px;