Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reconcile SDRPlay gains with SoapySDR abstractions #27

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
198 changes: 164 additions & 34 deletions Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -591,8 +591,11 @@ std::vector<std::string> SoapySDRPlay::listGains(const int direction, const size
//the functions below have a "name" parameter
std::vector<std::string> results;

results.push_back("IFGR");
results.push_back("RFGR");
// 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;
}
Expand Down Expand Up @@ -624,32 +627,166 @@ 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;
}
}

// 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 <std::mutex> lock(_general_state_mutex);
bool doUpdate = false;

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:
rfGR = rsp1_lnastates[index];
ifGR = rsp1_ifgains[index];
break;
case SDRPLAY_RSP1A_ID:
rfGR = rsp1a_lnastates[index];
ifGR = rsp1a_ifgains[index];
break;
case SDRPLAY_RSP2_ID:
rfGR = rsp2_lnastates[index];
ifGR = rsp2_ifgains[index];
break;
case SDRPLAY_RSPduo_ID:
rfGR = rspduo_lnastates[index];
ifGR = rspduo_ifgains[index];
break;
case SDRPLAY_RSPdx_ID:
rfGR = rspdx_lnastates[index];
ifGR = rspdx_ifgains[index];
break;
}

if (chParams->tunerParams.gain.gRdB != ifGR && chParams->ctrlParams.agc.enable == sdrplay_api_AGC_DISABLE)
{
chParams->tunerParams.gain.gRdB = ifGR;
doUpdate = true;
}

if (chParams->tunerParams.gain.LNAstate != rfGR)
{
chParams->tunerParams.gain.LNAstate = rfGR;
doUpdate = true;
}

if (doUpdate && streamActive)
{
sdrplay_api_Update(device.dev, device.tuner, sdrplay_api_Update_Tuner_Gr,
sdrplay_api_Update_Ext1_None);
}
}

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 <std::mutex> lock(_general_state_mutex);

bool doUpdate = false;

if (name == "IFGR" && chParams->ctrlParams.agc.enable == sdrplay_api_AGC_DISABLE)
if (chParams->ctrlParams.agc.enable == sdrplay_api_AGC_DISABLE)
{
if (name == "IFGR" || name == "IF")
{
return;
}
}

if (name == "IF" || name == "IFGR")
{
//apply the change if the required value is different from gRdB
if (chParams->tunerParams.gain.gRdB != (int)value)
int ifGR = (name == "IF") ? -value : value;
if (chParams->tunerParams.gain.gRdB != ifGR)
{
chParams->tunerParams.gain.gRdB = (int)value;
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") ? -value : value;
if (chParams->tunerParams.gain.LNAstate != rfGR) {

chParams->tunerParams.gain.LNAstate = (int)value;
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);
}
}

Expand All @@ -661,10 +798,18 @@ double SoapySDRPlay::getGain(const int direction, const size_t channel, const st
{
return chParams->tunerParams.gain.gRdB;
}
else if (name == "IF")
{
return -(chParams->tunerParams.gain.gRdB);
}
else if (name == "RFGR")
{
return chParams->tunerParams.gain.LNAstate;
}
else if (name == "RF")
{
return -(chParams->tunerParams.gain.LNAstate);
}

return 0;
}
Expand All @@ -675,27 +820,18 @@ SoapySDR::Range SoapySDRPlay::getGainRange(const int direction, const size_t cha
{
return SoapySDR::Range(20, 59);
}
else if ((name == "RFGR") && (device.hwVer == SDRPLAY_RSP1_ID))
{
return SoapySDR::Range(0, 3);
}
else if ((name == "RFGR") && (device.hwVer == SDRPLAY_RSP2_ID))
{
return SoapySDR::Range(0, 8);
}
else if ((name == "RFGR") && (device.hwVer == SDRPLAY_RSPduo_ID))
else if (name == "IF")
{
return SoapySDR::Range(0, 9);
return SoapySDR::Range(-59, -20);
}
else if ((name == "RFGR") && (device.hwVer == SDRPLAY_RSP1A_ID))
else if (name == "RFGR")
{
return SoapySDR::Range(0, 9);
return SoapySDR::Range(0, getMaxRFGR(device.hwVer));
}
else if ((name == "RFGR") && (device.hwVer == SDRPLAY_RSPdx_ID))
else // name == "RF"
{
return SoapySDR::Range(0, 27);
return SoapySDR::Range(-getMaxRFGR(device.hwVer), 0);
}
return SoapySDR::Range(20, 59);
}

/*******************************************************************
Expand Down Expand Up @@ -1176,7 +1312,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;
Expand Down Expand Up @@ -1288,7 +1423,7 @@ SoapySDR::ArgInfoList SoapySDRPlay::getSettingInfo(void) const
RfGainArg.options.push_back("3");
setArgs.push_back(RfGainArg);
}
#endif
//#endif

SoapySDR::ArgInfo IQcorrArg;
IQcorrArg.key = "iqcorr_ctrl";
Expand Down Expand Up @@ -1427,14 +1562,12 @@ void SoapySDRPlay::writeSetting(const std::string &key, const std::string &value
{
std::lock_guard <std::mutex> lock(_general_state_mutex);

#ifdef RF_GAIN_IN_MENU
if (key == "rfgain_sel")
{
chParams->tunerParams.gain.LNAstate = static_cast<unsigned char>(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;
Expand Down Expand Up @@ -1602,14 +1735,11 @@ std::string SoapySDRPlay::readSetting(const std::string &key) const
{
std::lock_guard <std::mutex> lock(_general_state_mutex);

#ifdef RF_GAIN_IN_MENU
if (key == "rfgain_sel")
{
return std::to_string(static_cast<unsigned int>(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";
Expand Down
6 changes: 6 additions & 0 deletions SoapySDRPlay.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -144,12 +146,16 @@ 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;

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
******************************************************************/
Expand Down