From 76e440fd87ada951d31249e9c949f46f00594224 Mon Sep 17 00:00:00 2001 From: SDRplay Date: Fri, 29 May 2020 08:41:05 +0100 Subject: [PATCH 1/4] added support for IFGain, RFGain and gain (0-29) --- CMakeLists.txt | 7 --- Settings.cpp | 134 ++++++++++++++++++++++++++++++++++++++++++----- SoapySDRPlay.hpp | 4 ++ 3 files changed, 125 insertions(+), 20 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 268a02a..344d8c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,13 +32,6 @@ if(CMAKE_COMPILER_IS_GNUCXX) add_definitions(-Wno-unused-parameter) endif(CMAKE_COMPILER_IS_GNUCXX) -# Configurable feature set -SET (RF_GAIN_IN_MENU ON CACHE BOOL "Add Rf gain as a setting, additionally to the IFGR gain control") - -IF(RF_GAIN_IN_MENU) - ADD_DEFINITIONS( -DRF_GAIN_IN_MENU=1 ) -ENDIF() - SET (STREAMING_USB_MODE_BULK OFF CACHE BOOL "Use USB bulk mode instead of isochronous") IF(STREAMING_USB_MODE_BULK) diff --git a/Settings.cpp b/Settings.cpp index 8f6d5c6..16e234b 100644 --- a/Settings.cpp +++ b/Settings.cpp @@ -40,6 +40,19 @@ extern SoapySDRPlay *activeSoapySDRPlay; static sdrplay_api_DeviceT rspDevs[SDRPLAY_MAX_DEVICES]; +int maxRFGR; + +const uint8_t rsp1_gains_lnastates[] = { 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +const uint8_t rsp1_gains_ifgains[] = { 59,56,53,50,47,44,41,58,55,52,49,46,43,45,42,58,55,52,49,46,43,41,38,35,32,29,26,23,20 }; +const uint8_t rsp1a_gains_lnastates[] = { 9, 9, 9, 9, 9, 9, 8, 7, 7, 7, 7, 7, 6, 6, 5, 5, 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; +const uint8_t rsp1a_gains_ifgains[] = { 59,55,52,48,45,41,42,58,54,51,47,43,46,42,44,41,43,42,44,40,43,45,42,38,34,31,27,24,20 }; +const uint8_t rsp2_gains_lnastates[] = { 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 6, 5, 5, 4, 4, 4, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +const uint8_t rsp2_gains_ifgains[] = { 59,55,52,48,44,41,56,52,49,45,41,44,45,41,48,44,40,45,42,43,49,46,42,38,35,31,27,24,20 }; +const uint8_t rspduo_gains_lnastates[] = { 9, 9, 9, 9, 9, 9, 8, 7, 7, 7, 7, 7, 6, 6, 5, 5, 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; +const uint8_t rspduo_gains_ifgains[] = { 59,55,52,48,45,41,42,58,54,51,47,43,46,42,44,41,43,42,44,40,43,45,42,38,34,31,27,24,20 }; +const uint8_t rspdx_gains_lnastates[] = { 26,26,26,26,26,25,23,22,20,19,17,16,14,13,11,10, 8, 7, 5, 5, 5, 3, 2, 0, 0, 0, 0, 0, 0 }; +const uint8_t rspdx_gains_ifgains[] = { 59,55,50,46,41,40,42,40,42,40,42,41,42,41,43,41,43,41,49,45,40,42,40,42,38,33,29,24,20 }; + SoapySDRPlay::SoapySDRPlay(const SoapySDR::Kwargs &args) { if (args.count("label") == 0) @@ -592,7 +605,9 @@ std::vector SoapySDRPlay::listGains(const int direction, const size std::vector results; results.push_back("IFGR"); + results.push_back("IFGain"); results.push_back("RFGR"); + results.push_back("RFGain"); return results; } @@ -624,6 +639,69 @@ bool SoapySDRPlay::getGainMode(const int direction, const size_t channel) const return chParams->ctrlParams.agc.enable != sdrplay_api_AGC_DISABLE; } +void SoapySDRPlay::setGain(const int direction, const size_t channel, const double value) +{ + std::lock_guard lock(_general_state_mutex); + bool doUpdate = false; + int localIFGR; + int localRFGR; + int localGain; + + if ((int)value < 0) + { + localGain = 0; + } + else if ((int)value > GAIN_STEPS) + { + localGain = GAIN_STEPS; + } + else + { + localGain = (int)value; + } + + switch(device.hwVer) + { + case SDRPLAY_RSP1_ID: + localRFGR = rsp1_gains_lnastates[localGain]; + localIFGR = rsp1_gains_ifgains[localGain]; + break; + case SDRPLAY_RSP1A_ID: + localRFGR = rsp1a_gains_lnastates[localGain]; + localIFGR = rsp1a_gains_ifgains[localGain]; + break; + case SDRPLAY_RSP2_ID: + localRFGR = rsp2_gains_lnastates[localGain]; + localIFGR = rsp2_gains_ifgains[localGain]; + break; + case SDRPLAY_RSPduo_ID: + localRFGR = rspduo_gains_lnastates[localGain]; + localIFGR = rspduo_gains_ifgains[localGain]; + break; + case SDRPLAY_RSPdx_ID: + localRFGR = rspdx_gains_lnastates[localGain]; + localIFGR = rspdx_gains_ifgains[localGain]; + break; + } + + if (chParams->tunerParams.gain.gRdB != localIFGR && chParams->ctrlParams.agc.enable == sdrplay_api_AGC_DISABLE) + { + chParams->tunerParams.gain.gRdB = localIFGR; + doUpdate = true; + } + + if (chParams->tunerParams.gain.LNAstate != localRFGR) + { + chParams->tunerParams.gain.LNAstate = localRFGR; + doUpdate = true; + } + + if ((doUpdate == true) && (streamActive)) + { + sdrplay_api_Update(device.dev, device.tuner, sdrplay_api_Update_Tuner_Gr, sdrplay_api_Update_Ext1_None); + } +} + void SoapySDRPlay::setGain(const int direction, const size_t channel, const std::string &name, const double value) { std::lock_guard lock(_general_state_mutex); @@ -632,13 +710,21 @@ void SoapySDRPlay::setGain(const int direction, const size_t channel, const std: if (name == "IFGR" && chParams->ctrlParams.agc.enable == sdrplay_api_AGC_DISABLE) { - //apply the change if the required value is different from gRdB if (chParams->tunerParams.gain.gRdB != (int)value) { chParams->tunerParams.gain.gRdB = (int)value; doUpdate = true; } } + else if (name == "IFGain" && chParams->ctrlParams.agc.enable == sdrplay_api_AGC_DISABLE) + { + int localIFGR = (59 - (int)value) + 20; + if (chParams->tunerParams.gain.gRdB != localIFGR) + { + chParams->tunerParams.gain.gRdB = localIFGR; + doUpdate = true; + } + } else if (name == "RFGR") { if (chParams->tunerParams.gain.LNAstate != (int)value) { @@ -647,6 +733,15 @@ void SoapySDRPlay::setGain(const int direction, const size_t channel, const std: doUpdate = true; } } + else if (name == "RFGain") + { + int localRFGR = maxRFGR - (int)value; + if (chParams->tunerParams.gain.LNAstate != localRFGR) { + + chParams->tunerParams.gain.LNAstate = localRFGR; + doUpdate = true; + } + } if ((doUpdate == true) && (streamActive)) { sdrplay_api_Update(device.dev, device.tuner, sdrplay_api_Update_Tuner_Gr, sdrplay_api_Update_Ext1_None); @@ -661,37 +756,45 @@ double SoapySDRPlay::getGain(const int direction, const size_t channel, const st { return chParams->tunerParams.gain.gRdB; } + else if (name == "IFGain") + { + return (59 - chParams->tunerParams.gain.gRdB) + 20; + } else if (name == "RFGR") { return chParams->tunerParams.gain.LNAstate; } + else if (name == "RFGain") + { + return maxRFGR - chParams->tunerParams.gain.LNAstate; + } return 0; } SoapySDR::Range SoapySDRPlay::getGainRange(const int direction, const size_t channel, const std::string &name) const { - if (name == "IFGR") + if (name == "IFGR" || name == "IFGain") { return SoapySDR::Range(20, 59); } - else if ((name == "RFGR") && (device.hwVer == SDRPLAY_RSP1_ID)) + else if ((name == "RFGR" || name == "RFGain") && (device.hwVer == SDRPLAY_RSP1_ID)) { return SoapySDR::Range(0, 3); } - else if ((name == "RFGR") && (device.hwVer == SDRPLAY_RSP2_ID)) + else if ((name == "RFGR" || name == "RFGain") && (device.hwVer == SDRPLAY_RSP2_ID)) { return SoapySDR::Range(0, 8); } - else if ((name == "RFGR") && (device.hwVer == SDRPLAY_RSPduo_ID)) + else if ((name == "RFGR" || name == "RFGain") && (device.hwVer == SDRPLAY_RSPduo_ID)) { return SoapySDR::Range(0, 9); } - else if ((name == "RFGR") && (device.hwVer == SDRPLAY_RSP1A_ID)) + else if ((name == "RFGR" || name == "RFGain") && (device.hwVer == SDRPLAY_RSP1A_ID)) { return SoapySDR::Range(0, 9); } - else if ((name == "RFGR") && (device.hwVer == SDRPLAY_RSPdx_ID)) + else if ((name == "RFGR" || name == "RFGain") && (device.hwVer == SDRPLAY_RSPdx_ID)) { return SoapySDR::Range(0, 27); } @@ -1176,7 +1279,7 @@ SoapySDR::ArgInfoList SoapySDRPlay::getSettingInfo(void) const non_const_this->selectDevice(); } -#ifdef RF_GAIN_IN_MENU +//#ifdef RF_GAIN_IN_MENU if (device.hwVer == SDRPLAY_RSP2_ID) { SoapySDR::ArgInfo RfGainArg; @@ -1195,6 +1298,7 @@ SoapySDR::ArgInfoList SoapySDRPlay::getSettingInfo(void) const RfGainArg.options.push_back("7"); RfGainArg.options.push_back("8"); setArgs.push_back(RfGainArg); + maxRFGR = 8; } else if (device.hwVer == SDRPLAY_RSPduo_ID) { @@ -1215,6 +1319,7 @@ SoapySDR::ArgInfoList SoapySDRPlay::getSettingInfo(void) const RfGainArg.options.push_back("8"); RfGainArg.options.push_back("9"); setArgs.push_back(RfGainArg); + maxRFGR = 9; } else if (device.hwVer == SDRPLAY_RSP1A_ID) { @@ -1235,6 +1340,7 @@ SoapySDR::ArgInfoList SoapySDRPlay::getSettingInfo(void) const RfGainArg.options.push_back("8"); RfGainArg.options.push_back("9"); setArgs.push_back(RfGainArg); + maxRFGR = 9; } else if (device.hwVer == SDRPLAY_RSPdx_ID) { @@ -1273,6 +1379,7 @@ SoapySDR::ArgInfoList SoapySDRPlay::getSettingInfo(void) const RfGainArg.options.push_back("26"); RfGainArg.options.push_back("27"); setArgs.push_back(RfGainArg); + maxRFGR = 27; } else { @@ -1287,8 +1394,9 @@ SoapySDR::ArgInfoList SoapySDRPlay::getSettingInfo(void) const RfGainArg.options.push_back("2"); RfGainArg.options.push_back("3"); setArgs.push_back(RfGainArg); + maxRFGR = 3; } -#endif +//#endif SoapySDR::ArgInfo IQcorrArg; IQcorrArg.key = "iqcorr_ctrl"; @@ -1427,14 +1535,14 @@ void SoapySDRPlay::writeSetting(const std::string &key, const std::string &value { std::lock_guard lock(_general_state_mutex); -#ifdef RF_GAIN_IN_MENU +//#ifdef RF_GAIN_IN_MENU if (key == "rfgain_sel") { chParams->tunerParams.gain.LNAstate = static_cast(stoul(value)); sdrplay_api_Update(device.dev, device.tuner, sdrplay_api_Update_Tuner_Gr, sdrplay_api_Update_Ext1_None); } else -#endif +//#endif if (key == "iqcorr_ctrl") { if (value == "false") chParams->ctrlParams.dcOffset.IQenable = 0; @@ -1602,13 +1710,13 @@ std::string SoapySDRPlay::readSetting(const std::string &key) const { std::lock_guard lock(_general_state_mutex); -#ifdef RF_GAIN_IN_MENU +//#ifdef RF_GAIN_IN_MENU if (key == "rfgain_sel") { return std::to_string(static_cast(chParams->tunerParams.gain.LNAstate)); } else -#endif +//#endif if (key == "iqcorr_ctrl") { if (chParams->ctrlParams.dcOffset.IQenable == 0) return "false"; diff --git a/SoapySDRPlay.hpp b/SoapySDRPlay.hpp index 086e73e..4e35b9f 100644 --- a/SoapySDRPlay.hpp +++ b/SoapySDRPlay.hpp @@ -43,6 +43,8 @@ #define DEFAULT_NUM_BUFFERS (8) #define DEFAULT_ELEMS_PER_SAMPLE (2) +#define GAIN_STEPS (29) + class SoapySDRPlay: public SoapySDR::Device { public: @@ -144,6 +146,8 @@ class SoapySDRPlay: public SoapySDR::Device bool getGainMode(const int direction, const size_t channel) const; + void setGain(const int direction, const size_t channel, const double value); + void setGain(const int direction, const size_t channel, const std::string &name, const double value); double getGain(const int direction, const size_t channel, const std::string &name) const; From 58bb74d706c880f4b7185e2a5028342dfd6cc6bf Mon Sep 17 00:00:00 2001 From: Franco Venturi Date: Sat, 30 May 2020 11:33:15 -0400 Subject: [PATCH 2/4] fix: rename gain controls 'IF' and 'RF' and keep the old 'IFGR' and 'RFGR' without listing them for backward compatibility --- Settings.cpp | 206 +++++++++++++++++++++++++-------------------------- 1 file changed, 101 insertions(+), 105 deletions(-) diff --git a/Settings.cpp b/Settings.cpp index 16e234b..a892965 100644 --- a/Settings.cpp +++ b/Settings.cpp @@ -40,19 +40,6 @@ extern SoapySDRPlay *activeSoapySDRPlay; static sdrplay_api_DeviceT rspDevs[SDRPLAY_MAX_DEVICES]; -int maxRFGR; - -const uint8_t rsp1_gains_lnastates[] = { 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -const uint8_t rsp1_gains_ifgains[] = { 59,56,53,50,47,44,41,58,55,52,49,46,43,45,42,58,55,52,49,46,43,41,38,35,32,29,26,23,20 }; -const uint8_t rsp1a_gains_lnastates[] = { 9, 9, 9, 9, 9, 9, 8, 7, 7, 7, 7, 7, 6, 6, 5, 5, 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; -const uint8_t rsp1a_gains_ifgains[] = { 59,55,52,48,45,41,42,58,54,51,47,43,46,42,44,41,43,42,44,40,43,45,42,38,34,31,27,24,20 }; -const uint8_t rsp2_gains_lnastates[] = { 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 6, 5, 5, 4, 4, 4, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -const uint8_t rsp2_gains_ifgains[] = { 59,55,52,48,44,41,56,52,49,45,41,44,45,41,48,44,40,45,42,43,49,46,42,38,35,31,27,24,20 }; -const uint8_t rspduo_gains_lnastates[] = { 9, 9, 9, 9, 9, 9, 8, 7, 7, 7, 7, 7, 6, 6, 5, 5, 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; -const uint8_t rspduo_gains_ifgains[] = { 59,55,52,48,45,41,42,58,54,51,47,43,46,42,44,41,43,42,44,40,43,45,42,38,34,31,27,24,20 }; -const uint8_t rspdx_gains_lnastates[] = { 26,26,26,26,26,25,23,22,20,19,17,16,14,13,11,10, 8, 7, 5, 5, 5, 3, 2, 0, 0, 0, 0, 0, 0 }; -const uint8_t rspdx_gains_ifgains[] = { 59,55,50,46,41,40,42,40,42,40,42,41,42,41,43,41,43,41,49,45,40,42,40,42,38,33,29,24,20 }; - SoapySDRPlay::SoapySDRPlay(const SoapySDR::Kwargs &args) { if (args.count("label") == 0) @@ -604,10 +591,11 @@ std::vector SoapySDRPlay::listGains(const int direction, const size //the functions below have a "name" parameter std::vector results; - results.push_back("IFGR"); - results.push_back("IFGain"); - results.push_back("RFGR"); - results.push_back("RFGain"); + // only return the gains (not the GRs) + //results.push_back("IFGR"); + results.push_back("IF"); + //results.push_back("RFGR"); + results.push_back("RF"); return results; } @@ -639,66 +627,107 @@ bool SoapySDRPlay::getGainMode(const int direction, const size_t channel) const return chParams->ctrlParams.agc.enable != sdrplay_api_AGC_DISABLE; } +static int getMaxRFGR(unsigned char hwVer) +{ + switch(hwVer) + { + case SDRPLAY_RSP1_ID: + return 3; + case SDRPLAY_RSP1A_ID: + return 9; + case SDRPLAY_RSP2_ID: + return 8; + case SDRPLAY_RSPduo_ID: + return 9; + case SDRPLAY_RSPdx_ID: + return 27; + default: + return 0; + } +} + void SoapySDRPlay::setGain(const int direction, const size_t channel, const double value) { std::lock_guard lock(_general_state_mutex); bool doUpdate = false; - int localIFGR; - int localRFGR; - int localGain; - if ((int)value < 0) - { - localGain = 0; - } - else if ((int)value > GAIN_STEPS) - { - localGain = GAIN_STEPS; - } - else - { - localGain = (int)value; - } + const uint8_t rsp1_lnastates[] = { 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, + 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + const uint8_t rsp1_ifgains[] = { 59, 56, 53, 50, 47, 44, 41, 58, 55, 52, 49, + 46, 43, 45, 42, 58, 55, 52, 49, 46, 43, 41, 38, 35, 32, 29, 26, 23, 20 }; + const uint8_t rsp1a_lnastates[] = { 9, 9, 9, 9, 9, 9, 8, 7, 7, 7, 7, 7, 6, + 6, 5, 5, 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; + const uint8_t rsp1a_ifgains[] = { 59, 55, 52, 48, 45, 41, 42, 58, 54, 51, 47, + 43, 46, 42, 44, 41, 43, 42, 44, 40, 43, 45, 42, 38, 34, 31, 27, 24, 20 }; + const uint8_t rsp2_lnastates[] = { 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 6, 5, 5, + 4, 4, 4, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + const uint8_t rsp2_ifgains[] = { 59, 55, 52, 48, 44, 41, 56, 52, 49, 45, 41, + 44, 45, 41, 48, 44, 40, 45, 42, 43, 49, 46, 42, 38, 35, 31, 27, 24, 20 }; + const uint8_t rspduo_lnastates[] = { 9, 9, 9, 9, 9, 9, 8, 7, 7, 7, 7, 7, 6, + 6, 5, 5, 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; + const uint8_t rspduo_ifgains[] = { 59, 55, 52, 48, 45, 41, 42, 58, 54, 51, + 47, 43, 46, 42, 44, 41, 43, 42, 44, 40, 43, 45, 42, 38, 34, 31, 27, 24, + 20 }; + const uint8_t rspdx_lnastates[] = { 26, 26, 26, 26, 26, 25, 23, 22, 20, 19, + 17, 16, 14, 13, 11, 10, 8, 7, 5, 5, 5, 3, 2, 0, 0, 0, 0, 0, 0 }; + const uint8_t rspdx_ifgains[] = { 59, 55, 50, 46, 41, 40, 42, 40, 42, 40, 42, + 41, 42, 41, 43, 41, 43, 41, 49, 45, 40, 42, 40, 42, 38, 33, 29, 24, 20 }; + + int gain = std::max(0, (int)value); + int max_gain; + int rfGR = 0; + int ifGR = 0; switch(device.hwVer) { case SDRPLAY_RSP1_ID: - localRFGR = rsp1_gains_lnastates[localGain]; - localIFGR = rsp1_gains_ifgains[localGain]; + max_gain = sizeof(rsp1_lnastates) / sizeof(rsp1_lnastates[0]) - 1; + rfGR = rsp1_lnastates[std::min(gain, max_gain)]; + max_gain = sizeof(rsp1_ifgains) / sizeof(rsp1_ifgains[0]) - 1; + ifGR = rsp1_ifgains[std::min(gain, max_gain)]; break; case SDRPLAY_RSP1A_ID: - localRFGR = rsp1a_gains_lnastates[localGain]; - localIFGR = rsp1a_gains_ifgains[localGain]; + max_gain = sizeof(rsp1a_lnastates) / sizeof(rsp1a_lnastates[0]) - 1; + rfGR = rsp1a_lnastates[std::min(gain, max_gain)]; + max_gain = sizeof(rsp1a_ifgains) / sizeof(rsp1a_ifgains[0]) - 1; + ifGR = rsp1a_ifgains[std::min(gain, max_gain)]; break; case SDRPLAY_RSP2_ID: - localRFGR = rsp2_gains_lnastates[localGain]; - localIFGR = rsp2_gains_ifgains[localGain]; + max_gain = sizeof(rsp2_lnastates) / sizeof(rsp2_lnastates[0]) - 1; + rfGR = rsp2_lnastates[std::min(gain, max_gain)]; + max_gain = sizeof(rsp2_ifgains) / sizeof(rsp2_ifgains[0]) - 1; + ifGR = rsp2_ifgains[std::min(gain, max_gain)]; break; case SDRPLAY_RSPduo_ID: - localRFGR = rspduo_gains_lnastates[localGain]; - localIFGR = rspduo_gains_ifgains[localGain]; + max_gain = sizeof(rspduo_lnastates) / sizeof(rspduo_lnastates[0]) - 1; + rfGR = rspduo_lnastates[std::min(gain, max_gain)]; + max_gain = sizeof(rspduo_ifgains) / sizeof(rspduo_ifgains[0]) - 1; + ifGR = rspduo_ifgains[std::min(gain, max_gain)]; break; case SDRPLAY_RSPdx_ID: - localRFGR = rspdx_gains_lnastates[localGain]; - localIFGR = rspdx_gains_ifgains[localGain]; + max_gain = sizeof(rspdx_lnastates) / sizeof(rspdx_lnastates[0]) - 1; + rfGR = rspdx_lnastates[std::min(gain, max_gain)]; + max_gain = sizeof(rspdx_ifgains) / sizeof(rspdx_ifgains[0]) - 1; + ifGR = rspdx_ifgains[std::min(gain, max_gain)]; break; } - if (chParams->tunerParams.gain.gRdB != localIFGR && chParams->ctrlParams.agc.enable == sdrplay_api_AGC_DISABLE) + if (chParams->tunerParams.gain.gRdB != ifGR && chParams->ctrlParams.agc.enable == sdrplay_api_AGC_DISABLE) { - chParams->tunerParams.gain.gRdB = localIFGR; + chParams->tunerParams.gain.gRdB = ifGR; doUpdate = true; } - if (chParams->tunerParams.gain.LNAstate != localRFGR) + if (chParams->tunerParams.gain.LNAstate != rfGR) { - chParams->tunerParams.gain.LNAstate = localRFGR; + chParams->tunerParams.gain.LNAstate = rfGR; doUpdate = true; } - if ((doUpdate == true) && (streamActive)) + if (doUpdate && streamActive) { - sdrplay_api_Update(device.dev, device.tuner, sdrplay_api_Update_Tuner_Gr, sdrplay_api_Update_Ext1_None); + sdrplay_api_Update(device.dev, device.tuner, sdrplay_api_Update_Tuner_Gr, + sdrplay_api_Update_Ext1_None); } } @@ -708,43 +737,37 @@ void SoapySDRPlay::setGain(const int direction, const size_t channel, const std: bool doUpdate = false; - if (name == "IFGR" && chParams->ctrlParams.agc.enable == sdrplay_api_AGC_DISABLE) + if (chParams->ctrlParams.agc.enable == sdrplay_api_AGC_DISABLE) { - if (chParams->tunerParams.gain.gRdB != (int)value) + if (name == "IFGR" || name == "IF") { - chParams->tunerParams.gain.gRdB = (int)value; - doUpdate = true; + return; } } - else if (name == "IFGain" && chParams->ctrlParams.agc.enable == sdrplay_api_AGC_DISABLE) + + if (name == "IF" || name == "IFGR") { - int localIFGR = (59 - (int)value) + 20; - if (chParams->tunerParams.gain.gRdB != localIFGR) + int ifGR = (name == "IF") ? 20 + (59 - value) : value; + if (chParams->tunerParams.gain.gRdB != ifGR) { - chParams->tunerParams.gain.gRdB = localIFGR; + chParams->tunerParams.gain.gRdB = ifGR; doUpdate = true; } } - else if (name == "RFGR") + else if (name == "RF" || name == "RFGR") { - if (chParams->tunerParams.gain.LNAstate != (int)value) { + int rfGR = (name == "RF") ? getMaxRFGR(device.hwVer) - value : value; + if (chParams->tunerParams.gain.LNAstate != rfGR) { - chParams->tunerParams.gain.LNAstate = (int)value; + chParams->tunerParams.gain.LNAstate = rfGR; doUpdate = true; } } - else if (name == "RFGain") - { - int localRFGR = maxRFGR - (int)value; - if (chParams->tunerParams.gain.LNAstate != localRFGR) { - chParams->tunerParams.gain.LNAstate = localRFGR; - doUpdate = true; - } - } - if ((doUpdate == true) && (streamActive)) + if (doUpdate && streamActive) { - sdrplay_api_Update(device.dev, device.tuner, sdrplay_api_Update_Tuner_Gr, sdrplay_api_Update_Ext1_None); + sdrplay_api_Update(device.dev, device.tuner, sdrplay_api_Update_Tuner_Gr, + sdrplay_api_Update_Ext1_None); } } @@ -756,17 +779,17 @@ double SoapySDRPlay::getGain(const int direction, const size_t channel, const st { return chParams->tunerParams.gain.gRdB; } - else if (name == "IFGain") + else if (name == "IF") { - return (59 - chParams->tunerParams.gain.gRdB) + 20; + return 20 + (59 - chParams->tunerParams.gain.gRdB); } else if (name == "RFGR") { return chParams->tunerParams.gain.LNAstate; } - else if (name == "RFGain") + else if (name == "RF") { - return maxRFGR - chParams->tunerParams.gain.LNAstate; + return getMaxRFGR(device.hwVer) - chParams->tunerParams.gain.LNAstate; } return 0; @@ -774,31 +797,15 @@ double SoapySDRPlay::getGain(const int direction, const size_t channel, const st SoapySDR::Range SoapySDRPlay::getGainRange(const int direction, const size_t channel, const std::string &name) const { - if (name == "IFGR" || name == "IFGain") + if (name == "IFGR" || name == "IF") { return SoapySDR::Range(20, 59); } - else if ((name == "RFGR" || name == "RFGain") && (device.hwVer == SDRPLAY_RSP1_ID)) - { - return SoapySDR::Range(0, 3); - } - else if ((name == "RFGR" || name == "RFGain") && (device.hwVer == SDRPLAY_RSP2_ID)) + else if (name == "RFGR" || name == "RF") { - return SoapySDR::Range(0, 8); + return SoapySDR::Range(0, getMaxRFGR(device.hwVer)); } - else if ((name == "RFGR" || name == "RFGain") && (device.hwVer == SDRPLAY_RSPduo_ID)) - { - return SoapySDR::Range(0, 9); - } - else if ((name == "RFGR" || name == "RFGain") && (device.hwVer == SDRPLAY_RSP1A_ID)) - { - return SoapySDR::Range(0, 9); - } - else if ((name == "RFGR" || name == "RFGain") && (device.hwVer == SDRPLAY_RSPdx_ID)) - { - return SoapySDR::Range(0, 27); - } - return SoapySDR::Range(20, 59); + return SoapySDR::Range(20, 59); } /******************************************************************* @@ -1279,7 +1286,6 @@ SoapySDR::ArgInfoList SoapySDRPlay::getSettingInfo(void) const non_const_this->selectDevice(); } -//#ifdef RF_GAIN_IN_MENU if (device.hwVer == SDRPLAY_RSP2_ID) { SoapySDR::ArgInfo RfGainArg; @@ -1298,7 +1304,6 @@ SoapySDR::ArgInfoList SoapySDRPlay::getSettingInfo(void) const RfGainArg.options.push_back("7"); RfGainArg.options.push_back("8"); setArgs.push_back(RfGainArg); - maxRFGR = 8; } else if (device.hwVer == SDRPLAY_RSPduo_ID) { @@ -1319,7 +1324,6 @@ SoapySDR::ArgInfoList SoapySDRPlay::getSettingInfo(void) const RfGainArg.options.push_back("8"); RfGainArg.options.push_back("9"); setArgs.push_back(RfGainArg); - maxRFGR = 9; } else if (device.hwVer == SDRPLAY_RSP1A_ID) { @@ -1340,7 +1344,6 @@ SoapySDR::ArgInfoList SoapySDRPlay::getSettingInfo(void) const RfGainArg.options.push_back("8"); RfGainArg.options.push_back("9"); setArgs.push_back(RfGainArg); - maxRFGR = 9; } else if (device.hwVer == SDRPLAY_RSPdx_ID) { @@ -1379,7 +1382,6 @@ SoapySDR::ArgInfoList SoapySDRPlay::getSettingInfo(void) const RfGainArg.options.push_back("26"); RfGainArg.options.push_back("27"); setArgs.push_back(RfGainArg); - maxRFGR = 27; } else { @@ -1394,7 +1396,6 @@ SoapySDR::ArgInfoList SoapySDRPlay::getSettingInfo(void) const RfGainArg.options.push_back("2"); RfGainArg.options.push_back("3"); setArgs.push_back(RfGainArg); - maxRFGR = 3; } //#endif @@ -1535,14 +1536,12 @@ void SoapySDRPlay::writeSetting(const std::string &key, const std::string &value { std::lock_guard lock(_general_state_mutex); -//#ifdef RF_GAIN_IN_MENU if (key == "rfgain_sel") { chParams->tunerParams.gain.LNAstate = static_cast(stoul(value)); sdrplay_api_Update(device.dev, device.tuner, sdrplay_api_Update_Tuner_Gr, sdrplay_api_Update_Ext1_None); } else -//#endif if (key == "iqcorr_ctrl") { if (value == "false") chParams->ctrlParams.dcOffset.IQenable = 0; @@ -1710,14 +1709,11 @@ std::string SoapySDRPlay::readSetting(const std::string &key) const { std::lock_guard lock(_general_state_mutex); -//#ifdef RF_GAIN_IN_MENU if (key == "rfgain_sel") { return std::to_string(static_cast(chParams->tunerParams.gain.LNAstate)); } - else -//#endif - if (key == "iqcorr_ctrl") + else if (key == "iqcorr_ctrl") { if (chParams->ctrlParams.dcOffset.IQenable == 0) return "false"; else return "true"; From 89287b8e43dd7c04cf6dcebec4f728e9eff7828e Mon Sep 17 00:00:00 2001 From: David Lawrence Date: Sun, 3 Jan 2021 19:10:44 -0500 Subject: [PATCH 3/4] Use negative gain values to represent gain reductions. --- Settings.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/Settings.cpp b/Settings.cpp index a892965..0921691 100644 --- a/Settings.cpp +++ b/Settings.cpp @@ -747,7 +747,7 @@ void SoapySDRPlay::setGain(const int direction, const size_t channel, const std: if (name == "IF" || name == "IFGR") { - int ifGR = (name == "IF") ? 20 + (59 - value) : value; + int ifGR = (name == "IF") ? -value : value; if (chParams->tunerParams.gain.gRdB != ifGR) { chParams->tunerParams.gain.gRdB = ifGR; @@ -756,7 +756,7 @@ void SoapySDRPlay::setGain(const int direction, const size_t channel, const std: } else if (name == "RF" || name == "RFGR") { - int rfGR = (name == "RF") ? getMaxRFGR(device.hwVer) - value : value; + int rfGR = (name == "RF") ? -value : value; if (chParams->tunerParams.gain.LNAstate != rfGR) { chParams->tunerParams.gain.LNAstate = rfGR; @@ -781,7 +781,7 @@ double SoapySDRPlay::getGain(const int direction, const size_t channel, const st } else if (name == "IF") { - return 20 + (59 - chParams->tunerParams.gain.gRdB); + return -(chParams->tunerParams.gain.gRdB); } else if (name == "RFGR") { @@ -789,7 +789,7 @@ double SoapySDRPlay::getGain(const int direction, const size_t channel, const st } else if (name == "RF") { - return getMaxRFGR(device.hwVer) - chParams->tunerParams.gain.LNAstate; + return -(chParams->tunerParams.gain.LNAstate); } return 0; @@ -797,15 +797,22 @@ double SoapySDRPlay::getGain(const int direction, const size_t channel, const st SoapySDR::Range SoapySDRPlay::getGainRange(const int direction, const size_t channel, const std::string &name) const { - if (name == "IFGR" || name == "IF") + if (name == "IFGR") { return SoapySDR::Range(20, 59); } - else if (name == "RFGR" || name == "RF") + else if (name == "IF") + { + return SoapySDR::Range(-59, -20); + } + else if (name == "RFGR") { return SoapySDR::Range(0, getMaxRFGR(device.hwVer)); } - return SoapySDR::Range(20, 59); + else // name == "RF" + { + return SoapySDR::Range(-getMaxRFGR(device.hwVer), 0); + } } /******************************************************************* From 3593230f98f28249af369a5b56a0dc665a11e786 Mon Sep 17 00:00:00 2001 From: David Lawrence Date: Sun, 3 Jan 2021 19:37:26 -0500 Subject: [PATCH 4/4] Clean up the default gain assignment logic. --- Settings.cpp | 107 ++++++++++++++++++++++++++++------------------- SoapySDRPlay.hpp | 2 + 2 files changed, 65 insertions(+), 44 deletions(-) diff --git a/Settings.cpp b/Settings.cpp index 0921691..b8628cc 100644 --- a/Settings.cpp +++ b/Settings.cpp @@ -646,69 +646,83 @@ static int getMaxRFGR(unsigned char hwVer) } } +// There are 29 default gain settings, ranging from 0 to 28, which select a +// pre-determined optimum balance between LNA attenuation and IF attenuation. +// Larger values represent less attenuation (i.e. more gain), but note that +// this value is *not* in decibels. +#define NUM_DEFAULT_GAIN_SETTINGS 29 + void SoapySDRPlay::setGain(const int direction, const size_t channel, const double value) { std::lock_guard lock(_general_state_mutex); bool doUpdate = false; - const uint8_t rsp1_lnastates[] = { 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, - 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - const uint8_t rsp1_ifgains[] = { 59, 56, 53, 50, 47, 44, 41, 58, 55, 52, 49, - 46, 43, 45, 42, 58, 55, 52, 49, 46, 43, 41, 38, 35, 32, 29, 26, 23, 20 }; - const uint8_t rsp1a_lnastates[] = { 9, 9, 9, 9, 9, 9, 8, 7, 7, 7, 7, 7, 6, - 6, 5, 5, 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; - const uint8_t rsp1a_ifgains[] = { 59, 55, 52, 48, 45, 41, 42, 58, 54, 51, 47, - 43, 46, 42, 44, 41, 43, 42, 44, 40, 43, 45, 42, 38, 34, 31, 27, 24, 20 }; - const uint8_t rsp2_lnastates[] = { 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 6, 5, 5, - 4, 4, 4, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - const uint8_t rsp2_ifgains[] = { 59, 55, 52, 48, 44, 41, 56, 52, 49, 45, 41, - 44, 45, 41, 48, 44, 40, 45, 42, 43, 49, 46, 42, 38, 35, 31, 27, 24, 20 }; - const uint8_t rspduo_lnastates[] = { 9, 9, 9, 9, 9, 9, 8, 7, 7, 7, 7, 7, 6, - 6, 5, 5, 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; - const uint8_t rspduo_ifgains[] = { 59, 55, 52, 48, 45, 41, 42, 58, 54, 51, - 47, 43, 46, 42, 44, 41, 43, 42, 44, 40, 43, 45, 42, 38, 34, 31, 27, 24, - 20 }; - const uint8_t rspdx_lnastates[] = { 26, 26, 26, 26, 26, 25, 23, 22, 20, 19, - 17, 16, 14, 13, 11, 10, 8, 7, 5, 5, 5, 3, 2, 0, 0, 0, 0, 0, 0 }; - const uint8_t rspdx_ifgains[] = { 59, 55, 50, 46, 41, 40, 42, 40, 42, 40, 42, - 41, 42, 41, 43, 41, 43, 41, 49, 45, 40, 42, 40, 42, 38, 33, 29, 24, 20 }; - - int gain = std::max(0, (int)value); - int max_gain; + const uint8_t rsp1_lnastates[NUM_DEFAULT_GAIN_SETTINGS] = { + 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 2, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + const uint8_t rsp1_ifgains[NUM_DEFAULT_GAIN_SETTINGS] = { + 59, 56, 53, 50, 47, 44, 41, 58, 55, 52, 49, 46, 43, 45, 42, + 58, 55, 52, 49, 46, 43, 41, 38, 35, 32, 29, 26, 23, 20 + }; + const uint8_t rsp1a_lnastates[NUM_DEFAULT_GAIN_SETTINGS] = { + 9, 9, 9, 9, 9, 9, 8, 7, 7, 7, 7, 7, 6, 6, 5, + 5, 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 + }; + const uint8_t rsp1a_ifgains[NUM_DEFAULT_GAIN_SETTINGS] = { + 59, 55, 52, 48, 45, 41, 42, 58, 54, 51, 47, 43, 46, 42, 44, + 41, 43, 42, 44, 40, 43, 45, 42, 38, 34, 31, 27, 24, 20 + }; + const uint8_t rsp2_lnastates[NUM_DEFAULT_GAIN_SETTINGS] = { + 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 6, 5, 5, 4, + 4, 4, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + const uint8_t rsp2_ifgains[NUM_DEFAULT_GAIN_SETTINGS] = { + 59, 55, 52, 48, 44, 41, 56, 52, 49, 45, 41, 44, 45, 41, 48, + 44, 40, 45, 42, 43, 49, 46, 42, 38, 35, 31, 27, 24, 20 + }; + const uint8_t rspduo_lnastates[NUM_DEFAULT_GAIN_SETTINGS] = { + 9, 9, 9, 9, 9, 9, 8, 7, 7, 7, 7, 7, 6, 6, 5, + 5, 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 + }; + const uint8_t rspduo_ifgains[NUM_DEFAULT_GAIN_SETTINGS] = { + 59, 55, 52, 48, 45, 41, 42, 58, 54, 51, 47, 43, 46, 42, 44, + 41, 43, 42, 44, 40, 43, 45, 42, 38, 34, 31, 27, 24, 20 + }; + const uint8_t rspdx_lnastates[NUM_DEFAULT_GAIN_SETTINGS] = { + 26, 26, 26, 26, 26, 25, 23, 22, 20, 19, 17, 16, 14, 13, 11, + 10, 8, 7, 5, 5, 5, 3, 2, 0, 0, 0, 0, 0, 0 + }; + const uint8_t rspdx_ifgains[NUM_DEFAULT_GAIN_SETTINGS] = { + 59, 55, 50, 46, 41, 40, 42, 40, 42, 40, 42, 41, 42, 41, 43, + 41, 43, 41, 49, 45, 40, 42, 40, 42, 38, 33, 29, 24, 20 + }; + + int index = std::max(0, std::min(NUM_DEFAULT_GAIN_SETTINGS - 1, (int)value)); int rfGR = 0; int ifGR = 0; switch(device.hwVer) { case SDRPLAY_RSP1_ID: - max_gain = sizeof(rsp1_lnastates) / sizeof(rsp1_lnastates[0]) - 1; - rfGR = rsp1_lnastates[std::min(gain, max_gain)]; - max_gain = sizeof(rsp1_ifgains) / sizeof(rsp1_ifgains[0]) - 1; - ifGR = rsp1_ifgains[std::min(gain, max_gain)]; + rfGR = rsp1_lnastates[index]; + ifGR = rsp1_ifgains[index]; break; case SDRPLAY_RSP1A_ID: - max_gain = sizeof(rsp1a_lnastates) / sizeof(rsp1a_lnastates[0]) - 1; - rfGR = rsp1a_lnastates[std::min(gain, max_gain)]; - max_gain = sizeof(rsp1a_ifgains) / sizeof(rsp1a_ifgains[0]) - 1; - ifGR = rsp1a_ifgains[std::min(gain, max_gain)]; + rfGR = rsp1a_lnastates[index]; + ifGR = rsp1a_ifgains[index]; break; case SDRPLAY_RSP2_ID: - max_gain = sizeof(rsp2_lnastates) / sizeof(rsp2_lnastates[0]) - 1; - rfGR = rsp2_lnastates[std::min(gain, max_gain)]; - max_gain = sizeof(rsp2_ifgains) / sizeof(rsp2_ifgains[0]) - 1; - ifGR = rsp2_ifgains[std::min(gain, max_gain)]; + rfGR = rsp2_lnastates[index]; + ifGR = rsp2_ifgains[index]; break; case SDRPLAY_RSPduo_ID: - max_gain = sizeof(rspduo_lnastates) / sizeof(rspduo_lnastates[0]) - 1; - rfGR = rspduo_lnastates[std::min(gain, max_gain)]; - max_gain = sizeof(rspduo_ifgains) / sizeof(rspduo_ifgains[0]) - 1; - ifGR = rspduo_ifgains[std::min(gain, max_gain)]; + rfGR = rspduo_lnastates[index]; + ifGR = rspduo_ifgains[index]; break; case SDRPLAY_RSPdx_ID: - max_gain = sizeof(rspdx_lnastates) / sizeof(rspdx_lnastates[0]) - 1; - rfGR = rspdx_lnastates[std::min(gain, max_gain)]; - max_gain = sizeof(rspdx_ifgains) / sizeof(rspdx_ifgains[0]) - 1; - ifGR = rspdx_ifgains[std::min(gain, max_gain)]; + rfGR = rspdx_lnastates[index]; + ifGR = rspdx_ifgains[index]; break; } @@ -731,6 +745,11 @@ void SoapySDRPlay::setGain(const int direction, const size_t channel, const doub } } +SoapySDR::Range SoapySDRPlay::getGainRange(const int direction, const size_t channel) const +{ + return NUM_DEFAULT_GAIN_SETTINGS; +} + void SoapySDRPlay::setGain(const int direction, const size_t channel, const std::string &name, const double value) { std::lock_guard lock(_general_state_mutex); diff --git a/SoapySDRPlay.hpp b/SoapySDRPlay.hpp index 4e35b9f..18a03fd 100644 --- a/SoapySDRPlay.hpp +++ b/SoapySDRPlay.hpp @@ -154,6 +154,8 @@ class SoapySDRPlay: public SoapySDR::Device SoapySDR::Range getGainRange(const int direction, const size_t channel, const std::string &name) const; + SoapySDR::Range getGainRange(const int direction, const size_t channel) const; + /******************************************************************* * Frequency API ******************************************************************/