diff -Nru soapybladerf-0.3.5/debian/changelog soapybladerf-0.3.5/debian/changelog --- soapybladerf-0.3.5/debian/changelog 2018-03-22 00:54:56.000000000 +0000 +++ soapybladerf-0.3.5/debian/changelog 2019-09-11 20:37:17.000000000 +0000 @@ -1,3 +1,9 @@ +soapybladerf (0.3.5-1+rpi1) bullseye-staging; urgency=medium + + * Apply upstream commits adding support for bladerf2 + + -- Peter Michael Green Wed, 11 Sep 2019 20:37:17 +0000 + soapybladerf (0.3.5-1) unstable; urgency=medium * New upstream version 0.3.5 diff -Nru soapybladerf-0.3.5/debian/patches/bladerf2-10-641917174c4fc378e7512831a7e5ae01ee2f3a41.patch soapybladerf-0.3.5/debian/patches/bladerf2-10-641917174c4fc378e7512831a7e5ae01ee2f3a41.patch --- soapybladerf-0.3.5/debian/patches/bladerf2-10-641917174c4fc378e7512831a7e5ae01ee2f3a41.patch 1970-01-01 00:00:00.000000000 +0000 +++ soapybladerf-0.3.5/debian/patches/bladerf2-10-641917174c4fc378e7512831a7e5ae01ee2f3a41.patch 2019-09-11 20:35:46.000000000 +0000 @@ -0,0 +1,76 @@ +commit 641917174c4fc378e7512831a7e5ae01ee2f3a41 +Author: Josh Farwell +Date: Tue Aug 21 00:28:22 2018 -0700 + + getGainRange updates + + Signed-off-by: Josh Farwell + +diff --git a/bladeRF_Settings.cpp b/bladeRF_Settings.cpp +index 13db258..ff2ff1d 100644 +--- a/bladeRF_Settings.cpp ++++ b/bladeRF_Settings.cpp +@@ -524,8 +524,6 @@ double bladeRF_SoapySDR::getGain(const int direction, const size_t channel, cons + { + if (direction == SOAPY_SDR_RX and name == "FULL") ret = bladerf_get_gain_stage(_dev, _channel, "full", &gain); + else if (direction == SOAPY_SDR_TX and name == "DSA") ret = bladerf_get_gain_stage(_dev, _channel, "dsa", &gain); +- // if (direction == SOAPY_SDR_RX) ret = bladerf_get_gain(_dev, _channel, &gain); +- // else if (direction == SOAPY_SDR_TX) ret = bladerf_get_gain(_dev, _channel, &gain); + else throw std::runtime_error("setGain("+name+") -- unknown name"); + } + else throw std::runtime_error("setGain("+name+") -- unknown board type"); +@@ -544,12 +542,54 @@ double bladeRF_SoapySDR::getGain(const int direction, const size_t channel, cons + + SoapySDR::Range bladeRF_SoapySDR::getGainRange(const int direction, const size_t channel, const std::string &name) const + { ++ #ifndef LIBBLADERF_V2 + if (direction == SOAPY_SDR_RX and name == "LNA") return SoapySDR::Range(0, BLADERF_LNA_GAIN_MAX_DB); + if (direction == SOAPY_SDR_RX and name == "VGA1") return SoapySDR::Range(BLADERF_RXVGA1_GAIN_MIN, BLADERF_RXVGA1_GAIN_MAX); + if (direction == SOAPY_SDR_RX and name == "VGA2") return SoapySDR::Range(BLADERF_RXVGA2_GAIN_MIN, BLADERF_RXVGA2_GAIN_MAX); + if (direction == SOAPY_SDR_TX and name == "VGA1") return SoapySDR::Range(BLADERF_TXVGA1_GAIN_MIN, BLADERF_TXVGA1_GAIN_MAX); + if (direction == SOAPY_SDR_TX and name == "VGA2") return SoapySDR::Range(BLADERF_TXVGA2_GAIN_MIN, BLADERF_TXVGA2_GAIN_MAX); + else throw std::runtime_error("getGainRange("+name+") -- unknown name"); ++ #else ++ ++ const bladerf_range* range; ++ bladerf_fpga_size variant; ++ const char* stage; ++ int ret = 0; ++ ++ ret = bladerf_get_fpga_size(_dev, &variant); ++ ++ if (ret != 0) ++ { ++ SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_get_fpga_size(%i) returned %s", variant, _err2str(ret).c_str()); ++ throw std::runtime_error("getGainRange() " + _err2str(ret)); ++ } ++ ++ if (variant == BLADERF_FPGA_115KLE or variant == BLADERF_FPGA_40KLE) ++ { ++ if (direction == SOAPY_SDR_RX and name == "LNA") stage = "lna"; ++ else if (direction == SOAPY_SDR_RX and name == "VGA1") stage = "rxvga1"; ++ else if (direction == SOAPY_SDR_RX and name == "VGA2") stage = "rxvga2"; ++ else if (direction == SOAPY_SDR_TX and name == "VGA1") stage = "txvga1"; ++ else if (direction == SOAPY_SDR_TX and name == "VGA2") stage = "txvga2"; ++ else throw std::runtime_error("getGainRange("+name+") -- unknown name"); ++ } ++ else if (variant == BLADERF_FPGA_A4 or variant == BLADERF_FPGA_A9) ++ { ++ if (direction == SOAPY_SDR_RX and name == "FULL") stage = "full"; ++ else if (direction == SOAPY_SDR_TX and name == "DSA") stage = "dsa"; ++ else throw std::runtime_error("getGainRange("+name+") -- unknown name"); ++ } ++ else throw std::runtime_error("getGainRange() board not supported"); ++ ++ ret = bladerf_get_gain_stage_range(_dev, _toch(direction, channel), stage, &range); ++ ++ if (ret != 0) ++ { ++ SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_get_gain_stage_range(%s) returned %s", stage, _err2str(ret).c_str()); ++ throw std::runtime_error("getGainRange()" + _err2str(ret)); ++ } ++ return SoapySDR::Range(range->min, range->max); ++ #endif + } + + /******************************************************************* diff -Nru soapybladerf-0.3.5/debian/patches/bladerf2-11-7cf416b6a187a70ffc6f7491d6c301d1d8b3acf5.patch soapybladerf-0.3.5/debian/patches/bladerf2-11-7cf416b6a187a70ffc6f7491d6c301d1d8b3acf5.patch --- soapybladerf-0.3.5/debian/patches/bladerf2-11-7cf416b6a187a70ffc6f7491d6c301d1d8b3acf5.patch 1970-01-01 00:00:00.000000000 +0000 +++ soapybladerf-0.3.5/debian/patches/bladerf2-11-7cf416b6a187a70ffc6f7491d6c301d1d8b3acf5.patch 2019-09-11 20:35:46.000000000 +0000 @@ -0,0 +1,188 @@ +commit 7cf416b6a187a70ffc6f7491d6c301d1d8b3acf5 +Author: Josh Blum +Date: Mon Sep 3 19:36:55 2018 -0500 + + report board string, sample mode, loopback etc + + The loopback uses enum index and api to query display names for each enum + + The sample mode and xb200 are not advertised unless its a v1 + +diff --git a/bladeRF_Settings.cpp b/bladeRF_Settings.cpp +index ff2ff1d..09f46b3 100644 +--- a/bladeRF_Settings.cpp ++++ b/bladeRF_Settings.cpp +@@ -77,6 +77,14 @@ bladeRF_SoapySDR::~bladeRF_SoapySDR(void) + /******************************************************************* + * Identification API + ******************************************************************/ ++std::string bladeRF_SoapySDR::getHardwareKey(void) const ++{ ++ #ifndef LIBBLADERF_V2 ++ return "bladeRF"; ++ #else ++ return bladerf_get_board_name(_dev); ++ #endif ++} + + SoapySDR::Kwargs bladeRF_SoapySDR::getHardwareInfo(void) const + { +@@ -846,6 +854,8 @@ SoapySDR::ArgInfoList bladeRF_SoapySDR::getSettingInfo(void) const + { + SoapySDR::ArgInfoList setArgs; + ++ const bool isBladeRF1 = this->getNumChannels(SOAPY_SDR_RX) == 1; ++ + // XB200 setting + SoapySDR::ArgInfo xb200SettingArg; + xb200SettingArg.key = "xb200"; +@@ -870,7 +880,7 @@ SoapySDR::ArgInfoList bladeRF_SoapySDR::getSettingInfo(void) const + xb200SettingArg.options.push_back("custom"); + xb200SettingArg.optionNames.push_back("Filterbank: Custom"); + +- setArgs.push_back(xb200SettingArg); ++ if (isBladeRF1) setArgs.push_back(xb200SettingArg); + + // Sampling mode + SoapySDR::ArgInfo samplingModeArg; +@@ -884,9 +894,10 @@ SoapySDR::ArgInfoList bladeRF_SoapySDR::getSettingInfo(void) const + samplingModeArg.options.push_back("external"); + samplingModeArg.optionNames.push_back("Direct Sampling"); + +- setArgs.push_back(samplingModeArg); ++ if (isBladeRF1) setArgs.push_back(samplingModeArg); + + // Loopback ++ #ifndef LIBBLADERF_V2 + SoapySDR::ArgInfo lookbackArg; + lookbackArg.key = "loopback"; + lookbackArg.value = "disabled"; +@@ -911,6 +922,21 @@ SoapySDR::ArgInfoList bladeRF_SoapySDR::getSettingInfo(void) const + lookbackArg.optionNames.push_back("RF: TXMIX to LNA2"); + lookbackArg.options.push_back("rf_lna3"); + lookbackArg.optionNames.push_back("RF: TXMIX to LNA3"); ++ #else ++ SoapySDR::ArgInfo lookbackArg; ++ lookbackArg.key = "loopback"; ++ lookbackArg.value = std::to_string(int(BLADERF_LB_NONE)); ++ lookbackArg.name = "Loopback Mode"; ++ lookbackArg.description = "Enable/disable internal loopback"; ++ lookbackArg.type = SoapySDR::ArgInfo::INT; ++ const bladerf_loopback_modes *modes(nullptr); ++ const int numModes = bladerf_get_loopback_modes(_dev, &modes); ++ if (modes and numModes > 0) for (int i = 0; i < numModes; i++) ++ { ++ lookbackArg.options.push_back(std::to_string(int(modes[i].mode))); ++ lookbackArg.optionNames.push_back(modes[i].name); ++ } ++ #endif + + setArgs.push_back(lookbackArg); + +@@ -990,7 +1016,13 @@ std::string bladeRF_SoapySDR::readSetting(const std::string &key) const + } else if (key == "sampling_mode") { + return _samplingMode; + } else if (key == "loopback") { ++ #ifndef LIBBLADERF_V2 + return _loopbackMode; ++ #else ++ bladerf_loopback lb; ++ bladerf_get_loopback(_dev, &lb); ++ return std::to_string(int(lb)); ++ #endif + } else if (key == "reset") { + return ""; + } else if (key == "erase_stored_fpga") { +@@ -1166,12 +1198,9 @@ void bladeRF_SoapySDR::writeSetting(const std::string &key, const std::string &v + } + else if (key == "loopback") + { ++ #ifndef LIBBLADERF_V2 + // Verify that a valid setting has arrived +- #ifdef LIBBLADERF_V2 +- std::vector loopback_validSettings{ "disabled", "firmware", "bb_txlpf_rxvga2", "bb_txvga1_rxvga2", "bb_txlpf_rxlpf", "bb_txvga1_rxlpf", "rf_lna1", "rf_lna2", "rf_lna3", "rfic_bist"}; +- #else +- std::vector loopback_validSettings{ "disabled", "firmware", "bb_txlpf_rxvga2", "bb_txvga1_rxvga2", "bb_txlpf_rxlpf", "bb_txvga1_rxlpf", "rf_lna1", "rf_lna2", "rf_lna3"}; +- #endif ++ std::vector loopback_validSettings{ "disabled", "firmware", "bb_txlpf_rxvga2", "bb_txvga1_rxvga2", "bb_txlpf_rxlpf", "bb_txvga1_rxlpf", "rf_lna1", "rf_lna2", "rf_lna3" }; + if (std::find(std::begin(loopback_validSettings), std::end(loopback_validSettings), value) != std::end(loopback_validSettings)) + { + // --> Valid setting has arrived +@@ -1220,46 +1249,31 @@ void bladeRF_SoapySDR::writeSetting(const std::string &key, const std::string &v + // RF loopback. The TXMIX output, through the AUX PA, is connected to the output of LNA3. + loopback = bladerf_loopback::BLADERF_LB_RF_LNA3; + } +- #ifdef LIBBLADERF_V2 +- else if (value == "rfic_bist") +- { +- // RF IC Built In Self Test loopback. +- loopback = bladerf_loopback::BLADERF_LB_RFIC_BIST; +- } +- #endif + else + { + // Default: Disabled + // Disables loopback and returns to normal operation + loopback = bladerf_loopback::BLADERF_LB_NONE; + } +- #ifdef LIBBLADERF_V2 +- // Check if the loopback mode is supported by the board +- if (bladerf_is_loopback_mode_supported(_dev, loopback)) +- #else +- if (true) +- #endif +- { ++ #else ++ auto loopback = bladerf_loopback(std::stoi(value)); ++ if (bladerf_is_loopback_mode_supported(_dev, loopback)) ++ { ++ #endif + +- // If the loopback isn't already set, set the loopback +- bladerf_loopback _bladerf_loopback = bladerf_loopback::BLADERF_LB_NONE; +- bladerf_get_loopback(_dev, &_bladerf_loopback); +- if (_bladerf_loopback != loopback) ++ // If the loopback isn't already set, set the loopback ++ bladerf_loopback _bladerf_loopback = bladerf_loopback::BLADERF_LB_NONE; ++ bladerf_get_loopback(_dev, &_bladerf_loopback); ++ if (_bladerf_loopback != loopback) ++ { ++ SoapySDR::logf(SOAPY_SDR_INFO, "bladeRF: Loopback set '%s'", value.c_str()); ++ int ret = bladerf_set_loopback(_dev, loopback); ++ if (ret != 0) + { +- SoapySDR::logf(SOAPY_SDR_INFO, "bladeRF: Loopback set '%s'", value.c_str()); +- int ret = bladerf_set_loopback(_dev, loopback); +- if (ret != 0) +- { +- SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_set_loopback(%s) returned %s", value.c_str(), _err2str(ret).c_str()); +- throw std::runtime_error("writeSetting() " + _err2str(ret)); +- } ++ SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_set_loopback(%s) returned %s", value.c_str(), _err2str(ret).c_str()); ++ throw std::runtime_error("writeSetting() " + _err2str(ret)); + } + } +- else +- { +- // --> Invalid setting has arrived +- SoapySDR::logf(SOAPY_SDR_ERROR, "bladeRF: Loopback setting '%s' not available on this device.", value.c_str()); +- } + } + else + { +diff --git a/bladeRF_SoapySDR.hpp b/bladeRF_SoapySDR.hpp +index 6f3b662..79f04c6 100644 +--- a/bladeRF_SoapySDR.hpp ++++ b/bladeRF_SoapySDR.hpp +@@ -69,10 +69,7 @@ public: + return "bladeRF"; + } + +- std::string getHardwareKey(void) const +- { +- return "bladeRF"; +- } ++ std::string getHardwareKey(void) const; + + SoapySDR::Kwargs getHardwareInfo(void) const; + diff -Nru soapybladerf-0.3.5/debian/patches/bladerf2-12-f7e6007298a2bd2b5d1941a80ca0f384e0f2e49f.patch soapybladerf-0.3.5/debian/patches/bladerf2-12-f7e6007298a2bd2b5d1941a80ca0f384e0f2e49f.patch --- soapybladerf-0.3.5/debian/patches/bladerf2-12-f7e6007298a2bd2b5d1941a80ca0f384e0f2e49f.patch 1970-01-01 00:00:00.000000000 +0000 +++ soapybladerf-0.3.5/debian/patches/bladerf2-12-f7e6007298a2bd2b5d1941a80ca0f384e0f2e49f.patch 2019-09-11 20:35:46.000000000 +0000 @@ -0,0 +1,60 @@ +commit f7e6007298a2bd2b5d1941a80ca0f384e0f2e49f +Author: Josh Blum +Date: Fri Sep 7 20:53:11 2018 -0500 + + loopback mode use string value as key + +diff --git a/bladeRF_Settings.cpp b/bladeRF_Settings.cpp +index 09f46b3..2e5f118 100644 +--- a/bladeRF_Settings.cpp ++++ b/bladeRF_Settings.cpp +@@ -925,16 +925,15 @@ SoapySDR::ArgInfoList bladeRF_SoapySDR::getSettingInfo(void) const + #else + SoapySDR::ArgInfo lookbackArg; + lookbackArg.key = "loopback"; +- lookbackArg.value = std::to_string(int(BLADERF_LB_NONE)); + lookbackArg.name = "Loopback Mode"; + lookbackArg.description = "Enable/disable internal loopback"; +- lookbackArg.type = SoapySDR::ArgInfo::INT; ++ lookbackArg.type = SoapySDR::ArgInfo::STRING; + const bladerf_loopback_modes *modes(nullptr); + const int numModes = bladerf_get_loopback_modes(_dev, &modes); + if (modes and numModes > 0) for (int i = 0; i < numModes; i++) + { +- lookbackArg.options.push_back(std::to_string(int(modes[i].mode))); +- lookbackArg.optionNames.push_back(modes[i].name); ++ if (modes[i].mode == BLADERF_LB_NONE) lookbackArg.value = modes[i].name; ++ lookbackArg.options.push_back(modes[i].name); + } + #endif + +@@ -1021,7 +1020,13 @@ std::string bladeRF_SoapySDR::readSetting(const std::string &key) const + #else + bladerf_loopback lb; + bladerf_get_loopback(_dev, &lb); +- return std::to_string(int(lb)); ++ const bladerf_loopback_modes *modes(nullptr); ++ const int numModes = bladerf_get_loopback_modes(_dev, &modes); ++ if (modes and numModes > 0) for (int i = 0; i < numModes; i++) ++ { ++ if (modes[i].mode == lb) return modes[i].name; ++ } ++ return "unknown"; + #endif + } else if (key == "reset") { + return ""; +@@ -1256,7 +1261,13 @@ void bladeRF_SoapySDR::writeSetting(const std::string &key, const std::string &v + loopback = bladerf_loopback::BLADERF_LB_NONE; + } + #else +- auto loopback = bladerf_loopback(std::stoi(value)); ++ bladerf_loopback loopback(BLADERF_LB_NONE); ++ const bladerf_loopback_modes *modes(nullptr); ++ const int numModes = bladerf_get_loopback_modes(_dev, &modes); ++ if (modes and numModes > 0) for (int i = 0; i < numModes; i++) ++ { ++ if (modes[i].name == value) loopback = modes[i].mode; ++ } + if (bladerf_is_loopback_mode_supported(_dev, loopback)) + { + #endif diff -Nru soapybladerf-0.3.5/debian/patches/bladerf2-1-ffca4ab56218c6115c30ecb2cf3a65eeb43e581c.patch soapybladerf-0.3.5/debian/patches/bladerf2-1-ffca4ab56218c6115c30ecb2cf3a65eeb43e581c.patch --- soapybladerf-0.3.5/debian/patches/bladerf2-1-ffca4ab56218c6115c30ecb2cf3a65eeb43e581c.patch 1970-01-01 00:00:00.000000000 +0000 +++ soapybladerf-0.3.5/debian/patches/bladerf2-1-ffca4ab56218c6115c30ecb2cf3a65eeb43e581c.patch 2019-09-11 20:35:45.000000000 +0000 @@ -0,0 +1,511 @@ +commit ffca4ab56218c6115c30ecb2cf3a65eeb43e581c +Author: Josh Blum +Date: Fri Aug 17 19:22:43 2018 -0500 + + support bladerf multi-channel api + +diff --git a/bladeRF_Settings.cpp b/bladeRF_Settings.cpp +index dc8a05a..f2c7be1 100644 +--- a/bladeRF_Settings.cpp ++++ b/bladeRF_Settings.cpp +@@ -110,6 +110,24 @@ SoapySDR::Kwargs bladeRF_SoapySDR::getHardwareInfo(void) const + return info; + } + ++/******************************************************************* ++ * Channels API ++ ******************************************************************/ ++ ++size_t bladeRF_SoapySDR::getNumChannels(const int direction) const ++{ ++ #ifndef LIBBLADERF_V2 ++ return 1; ++ #else ++ return bladerf_get_channel_count(_dev, (direction == SOAPY_SDR_RX)?BLADERF_RX:BLADERF_TX); ++ #endif ++} ++ ++bool bladeRF_SoapySDR::getFullDuplex(const int, const size_t) const ++{ ++ return true; ++} ++ + /******************************************************************* + * Antenna API + ******************************************************************/ +@@ -143,7 +161,7 @@ bool bladeRF_SoapySDR::hasDCOffset(const int, const size_t) const + return true; + } + +-void bladeRF_SoapySDR::setDCOffset(const int direction, const size_t, const std::complex &offset) ++void bladeRF_SoapySDR::setDCOffset(const int direction, const size_t channel, const std::complex &offset) + { + int ret = 0; + int16_t i = 0; +@@ -159,14 +177,14 @@ void bladeRF_SoapySDR::setDCOffset(const int direction, const size_t, const std: + else + q = int16_t(offset.imag() * 2048); + +- ret = bladerf_set_correction(_dev, _dir2mod(direction), BLADERF_CORR_LMS_DCOFF_I, i); ++ ret = bladerf_set_correction(_dev, _toch(direction, channel), BLADERF_CORR_LMS_DCOFF_I, i); + if (ret != 0) + { + SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_set_correction(%f) returned %s", i, _err2str(ret).c_str()); + throw std::runtime_error("setDCOffset() " + _err2str(ret)); + } + +- ret = bladerf_set_correction(_dev, _dir2mod(direction), BLADERF_CORR_LMS_DCOFF_Q, q); ++ ret = bladerf_set_correction(_dev, _toch(direction, channel), BLADERF_CORR_LMS_DCOFF_Q, q); + if (ret != 0) + { + SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_set_correction(%f) returned %s", q, _err2str(ret).c_str()); +@@ -174,20 +192,20 @@ void bladeRF_SoapySDR::setDCOffset(const int direction, const size_t, const std: + } + } + +-std::complex bladeRF_SoapySDR::getDCOffset(const int direction, const size_t) const ++std::complex bladeRF_SoapySDR::getDCOffset(const int direction, const size_t channel) const + { + int ret = 0; + int16_t i = 0; + int16_t q = 0; + +- ret = bladerf_get_correction(_dev, _dir2mod(direction), BLADERF_CORR_LMS_DCOFF_I, &i); ++ ret = bladerf_get_correction(_dev, _toch(direction, channel), BLADERF_CORR_LMS_DCOFF_I, &i); + if (ret != 0) + { + SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_get_correction() returned %s", _err2str(ret).c_str()); + throw std::runtime_error("getDCOffset() " + _err2str(ret)); + } + +- ret = bladerf_get_correction(_dev, _dir2mod(direction), BLADERF_CORR_LMS_DCOFF_Q, &q); ++ ret = bladerf_get_correction(_dev, _toch(direction, channel), BLADERF_CORR_LMS_DCOFF_Q, &q); + if (ret != 0) + { + SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_get_correction() returned %s", _err2str(ret).c_str()); +@@ -198,12 +216,12 @@ std::complex bladeRF_SoapySDR::getDCOffset(const int direction, const si + return z; + } + +-bool bladeRF_SoapySDR::hasIQBalance(const int, const size_t) const ++bool bladeRF_SoapySDR::hasIQBalance(const int, const size_t channel) const + { + return true; + } + +-void bladeRF_SoapySDR::setIQBalance(const int direction, const size_t, const std::complex &balance) ++void bladeRF_SoapySDR::setIQBalance(const int direction, const size_t channel, const std::complex &balance) + { + int ret = 0; + int16_t gain = 0; +@@ -219,14 +237,14 @@ void bladeRF_SoapySDR::setIQBalance(const int direction, const size_t, const std + else + phase = int16_t(balance.imag() * 4096); + +- ret = bladerf_set_correction(_dev, _dir2mod(direction), BLADERF_CORR_FPGA_GAIN, gain); ++ ret = bladerf_set_correction(_dev, _toch(direction, channel), BLADERF_CORR_FPGA_GAIN, gain); + if (ret != 0) + { + SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_set_correction(%f) returned %s", gain, _err2str(ret).c_str()); + throw std::runtime_error("setIQBalance() " + _err2str(ret)); + } + +- ret = bladerf_set_correction(_dev, _dir2mod(direction), BLADERF_CORR_FPGA_PHASE, phase); ++ ret = bladerf_set_correction(_dev, _toch(direction, channel), BLADERF_CORR_FPGA_PHASE, phase); + if (ret != 0) + { + SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_set_correction(%f) returned %s", phase, _err2str(ret).c_str()); +@@ -234,20 +252,20 @@ void bladeRF_SoapySDR::setIQBalance(const int direction, const size_t, const std + } + } + +-std::complex bladeRF_SoapySDR::getIQBalance(const int direction, const size_t) const ++std::complex bladeRF_SoapySDR::getIQBalance(const int direction, const size_t channel) const + { + int ret = 0; + int16_t gain = 0; + int16_t phase = 0; + +- ret = bladerf_get_correction(_dev, _dir2mod(direction), BLADERF_CORR_FPGA_GAIN, &gain); ++ ret = bladerf_get_correction(_dev, _toch(direction, channel), BLADERF_CORR_FPGA_GAIN, &gain); + if (ret != 0) + { + SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_get_correction() returned %s", _err2str(ret).c_str()); + throw std::runtime_error("getIQBalance() " + _err2str(ret)); + } + +- ret = bladerf_get_correction(_dev, _dir2mod(direction), BLADERF_CORR_FPGA_PHASE, &phase); ++ ret = bladerf_get_correction(_dev, _toch(direction, channel), BLADERF_CORR_FPGA_PHASE, &phase); + if (ret != 0) + { + SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_get_correction() returned %s", _err2str(ret).c_str()); +@@ -262,21 +280,21 @@ std::complex bladeRF_SoapySDR::getIQBalance(const int direction, const s + * Gain API + ******************************************************************/ + +-bool bladeRF_SoapySDR::hasGainMode(const int direction, const size_t) const ++bool bladeRF_SoapySDR::hasGainMode(const int direction, const size_t channel) const + { + #ifdef HAS_BLADERF_GAIN_MODE +- return _dir2mod(direction) == BLADERF_MODULE_RX ? true : false; ++ return _toch(direction, channel) == BLADERF_MODULE_RX ? true : false; + #else + return false; + #endif + } + +-void bladeRF_SoapySDR::setGainMode(const int direction, const size_t, const bool automatic) ++void bladeRF_SoapySDR::setGainMode(const int direction, const size_t channel, const bool automatic) + { + #ifdef HAS_BLADERF_GAIN_MODE + if (direction == SOAPY_SDR_TX) return; //not supported on tx + bladerf_gain_mode gain_mode = automatic ? BLADERF_GAIN_AUTOMATIC : BLADERF_GAIN_MANUAL; +- const int ret = bladerf_set_gain_mode(_dev, _dir2mod(direction), gain_mode); ++ const int ret = bladerf_set_gain_mode(_dev, _toch(direction, channel), gain_mode); + if (ret != 0 and automatic) //only throw when mode is automatic, manual is default even when call bombs + { + SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_set_gain_mode(%s) returned %s", automatic?"automatic":"manual", _err2str(ret).c_str()); +@@ -285,14 +303,14 @@ void bladeRF_SoapySDR::setGainMode(const int direction, const size_t, const bool + #endif + } + +-bool bladeRF_SoapySDR::getGainMode(const int direction, const size_t) const ++bool bladeRF_SoapySDR::getGainMode(const int direction, const size_t channel) const + { + #ifdef HAS_BLADERF_GAIN_MODE + if (direction == SOAPY_SDR_TX) return false; //not supported on tx + int ret = 0; + bladerf_gain_mode gain_mode; + bool automatic; +- ret = bladerf_get_gain_mode(_dev, _dir2mod(direction), &gain_mode); ++ ret = bladerf_get_gain_mode(_dev, _toch(direction, channel), &gain_mode); + if (ret != 0) + { + SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_get_gain_mode() returned %s", _err2str(ret).c_str()); +@@ -306,7 +324,7 @@ bool bladeRF_SoapySDR::getGainMode(const int direction, const size_t) const + #endif + } + +-std::vector bladeRF_SoapySDR::listGains(const int direction, const size_t) const ++std::vector bladeRF_SoapySDR::listGains(const int direction, const size_t channel) const + { + std::vector options; + if (direction == SOAPY_SDR_RX) options.push_back("LNA"); +@@ -315,9 +333,9 @@ std::vector bladeRF_SoapySDR::listGains(const int direction, const + return options; + } + +-void bladeRF_SoapySDR::setGain(const int direction, const size_t, const double value) ++void bladeRF_SoapySDR::setGain(const int direction, const size_t channel, const double value) + { +- const int ret = bladerf_set_gain(_dev, _dir2mod(direction), int(value)); ++ const int ret = bladerf_set_gain(_dev, _toch(direction, channel), int(value)); + if (ret != 0) + { + SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_set_gain(%f) returned %s", value, _err2str(ret).c_str()); +@@ -325,7 +343,7 @@ void bladeRF_SoapySDR::setGain(const int direction, const size_t, const double v + } + } + +-void bladeRF_SoapySDR::setGain(const int direction, const size_t, const std::string &name, const double value) ++void bladeRF_SoapySDR::setGain(const int direction, const size_t channel, const std::string &name, const double value) + { + int ret = 0; + if (direction == SOAPY_SDR_RX and name == "LNA") +@@ -346,7 +364,7 @@ void bladeRF_SoapySDR::setGain(const int direction, const size_t, const std::str + } + } + +-double bladeRF_SoapySDR::getGain(const int direction, const size_t, const std::string &name) const ++double bladeRF_SoapySDR::getGain(const int direction, const size_t channel, const std::string &name) const + { + int ret = 0; + int gain = 0; +@@ -375,7 +393,7 @@ double bladeRF_SoapySDR::getGain(const int direction, const size_t, const std::s + return gain; + } + +-SoapySDR::Range bladeRF_SoapySDR::getGainRange(const int direction, const size_t, const std::string &name) const ++SoapySDR::Range bladeRF_SoapySDR::getGainRange(const int direction, const size_t channel, const std::string &name) const + { + if (direction == SOAPY_SDR_RX and name == "LNA") return SoapySDR::Range(0, BLADERF_LNA_GAIN_MAX_DB); + if (direction == SOAPY_SDR_RX and name == "VGA1") return SoapySDR::Range(BLADERF_RXVGA1_GAIN_MIN, BLADERF_RXVGA1_GAIN_MAX); +@@ -389,12 +407,12 @@ SoapySDR::Range bladeRF_SoapySDR::getGainRange(const int direction, const size_t + * Frequency API + ******************************************************************/ + +-void bladeRF_SoapySDR::setFrequency(const int direction, const size_t, const std::string &name, const double frequency, const SoapySDR::Kwargs &) ++void bladeRF_SoapySDR::setFrequency(const int direction, const size_t channel, const std::string &name, const double frequency, const SoapySDR::Kwargs &) + { + if (name == "BB") return; //for compatibility + if (name != "RF") throw std::runtime_error("setFrequency("+name+") unknown name"); + +- int ret = bladerf_set_frequency(_dev, _dir2mod(direction), (unsigned int)(frequency)); ++ int ret = bladerf_set_frequency(_dev, _toch(direction, channel), (unsigned int)(frequency)); + if (ret != 0) + { + SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_set_frequency(%f) returned %s", frequency, _err2str(ret).c_str()); +@@ -402,13 +420,13 @@ void bladeRF_SoapySDR::setFrequency(const int direction, const size_t, const std + } + } + +-double bladeRF_SoapySDR::getFrequency(const int direction, const size_t, const std::string &name) const ++double bladeRF_SoapySDR::getFrequency(const int direction, const size_t channel, const std::string &name) const + { + if (name == "BB") return 0.0; //for compatibility + if (name != "RF") throw std::runtime_error("getFrequency("+name+") unknown name"); + +- unsigned int freq = 0; +- int ret = bladerf_get_frequency(_dev, _dir2mod(direction), &freq); ++ bladerf_frequency freq = 0; ++ int ret = bladerf_get_frequency(_dev, _toch(direction, channel), &freq); + if (ret != 0) + { + SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_get_frequency() returned %s", _err2str(ret).c_str()); +@@ -417,14 +435,14 @@ double bladeRF_SoapySDR::getFrequency(const int direction, const size_t, const s + return freq; + } + +-std::vector bladeRF_SoapySDR::listFrequencies(const int, const size_t) const ++std::vector bladeRF_SoapySDR::listFrequencies(const int, const size_t channel) const + { + std::vector components; + components.push_back("RF"); + return components; + } + +-SoapySDR::RangeList bladeRF_SoapySDR::getFrequencyRange(const int, const size_t, const std::string &name) const ++SoapySDR::RangeList bladeRF_SoapySDR::getFrequencyRange(const int, const size_t channel, const std::string &name) const + { + if (name == "BB") return SoapySDR::RangeList(1, SoapySDR::Range(0.0, 0.0)); //for compatibility + if (name != "RF") throw std::runtime_error("getFrequencyRange("+name+") unknown name"); +@@ -448,7 +466,7 @@ void bladeRF_SoapySDR::setSampleRate(const int direction, const size_t channel, + //stash the approximate hardware time so it can be restored + const long long timeNow = this->getHardwareTime(); + +- int ret = bladerf_set_rational_sample_rate(_dev, _dir2mod(direction), &ratRate, NULL); ++ int ret = bladerf_set_rational_sample_rate(_dev, _toch(direction, channel), &ratRate, NULL); + if (ret != 0) + { + SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_set_rational_sample_rate(%f) returned %s", rate, _err2str(ret).c_str()); +@@ -473,10 +491,10 @@ void bladeRF_SoapySDR::setSampleRate(const int direction, const size_t channel, + SoapySDR::logf(SOAPY_SDR_INFO, "setSampleRate(%d, %f MHz), actual = %f MHz", direction, rate/1e6, actual/1e6); + } + +-double bladeRF_SoapySDR::getSampleRate(const int direction, const size_t) const ++double bladeRF_SoapySDR::getSampleRate(const int direction, const size_t channel) const + { + bladerf_rational_rate ratRate; +- int ret = bladerf_get_rational_sample_rate(_dev, _dir2mod(direction), &ratRate); ++ int ret = bladerf_get_rational_sample_rate(_dev, _toch(direction, channel), &ratRate); + if (ret != 0) + { + SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_get_rational_sample_rate() returned %s", _err2str(ret).c_str()); +@@ -486,7 +504,7 @@ double bladeRF_SoapySDR::getSampleRate(const int direction, const size_t) const + return double(ratRate.integer) + (double(ratRate.num)/double(ratRate.den)); + } + +-std::vector bladeRF_SoapySDR::listSampleRates(const int, const size_t) const ++std::vector bladeRF_SoapySDR::listSampleRates(const int, const size_t channel) const + { + std::vector options; + for (double r = 160e3; r <= 200e3; r += 40e3) options.push_back(r); +@@ -497,18 +515,18 @@ std::vector bladeRF_SoapySDR::listSampleRates(const int, const size_t) c + return options; + } + +-void bladeRF_SoapySDR::setBandwidth(const int direction, const size_t, const double bw) ++void bladeRF_SoapySDR::setBandwidth(const int direction, const size_t channel, const double bw) + { + //bypass the filter when sufficiently large BW is selected + if (bw > BLADERF_BANDWIDTH_MAX) + { +- bladerf_set_lpf_mode(_dev, _dir2mod(direction), BLADERF_LPF_BYPASSED); ++ bladerf_set_lpf_mode(_dev, _toch(direction, channel), BLADERF_LPF_BYPASSED); + return; + } + + //otherwise set to normal and configure the filter bandwidth +- bladerf_set_lpf_mode(_dev, _dir2mod(direction), BLADERF_LPF_NORMAL); +- int ret = bladerf_set_bandwidth(_dev, _dir2mod(direction), (unsigned int)(bw), NULL); ++ bladerf_set_lpf_mode(_dev, _toch(direction, channel), BLADERF_LPF_NORMAL); ++ int ret = bladerf_set_bandwidth(_dev, _toch(direction, channel), (unsigned int)(bw), NULL); + if (ret != 0) + { + SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_set_bandwidth(%f) returned %s", bw, _err2str(ret).c_str()); +@@ -516,10 +534,10 @@ void bladeRF_SoapySDR::setBandwidth(const int direction, const size_t, const dou + } + } + +-double bladeRF_SoapySDR::getBandwidth(const int direction, const size_t) const ++double bladeRF_SoapySDR::getBandwidth(const int direction, const size_t channel) const + { + unsigned int bw = 0; +- int ret = bladerf_get_bandwidth(_dev, _dir2mod(direction), &bw); ++ int ret = bladerf_get_bandwidth(_dev, _toch(direction, channel), &bw); + if (ret != 0) + { + SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_get_bandwidth() returned %s", _err2str(ret).c_str()); +@@ -567,7 +585,11 @@ long long bladeRF_SoapySDR::getHardwareTime(const std::string &what) const + { + if (not what.empty()) return SoapySDR::Device::getHardwareTime(what); + uint64_t ticksNow = 0; ++ #ifndef LIBBLADERF_V2 + const int ret = bladerf_get_timestamp(_dev, BLADERF_MODULE_RX, &ticksNow); ++ #else ++ const int ret = bladerf_get_timestamp(_dev, BLADERF_RX, &ticksNow); ++ #endif + + if (ret != 0) + { +@@ -802,6 +824,7 @@ void bladeRF_SoapySDR::writeSetting(const std::string &key, const std::string &v + { + if (key == "xb200") + { ++ #ifndef LIBBLADERF_V2 + // Verify that a valid setting has arrived + std::vector xb200_validSettings{ "disabled", "50M", "144M", "222M", "auto1db", "auto3db", "auto", "custom" }; + if (std::find(std::begin(xb200_validSettings), std::end(xb200_validSettings), value) != std::end(xb200_validSettings)) +@@ -909,6 +932,7 @@ void bladeRF_SoapySDR::writeSetting(const std::string &key, const std::string &v + SoapySDR::logf(SOAPY_SDR_ERROR, "bladeRF: Invalid XB200 setting '%s'", value.c_str()); + //throw std::runtime_error("writeSetting(" + key + "," + value + ") unknown value"); + } ++ #endif + } + else if (key == "sampling_mode") + { +diff --git a/bladeRF_SoapySDR.hpp b/bladeRF_SoapySDR.hpp +index 1df286f..da0a767 100644 +--- a/bladeRF_SoapySDR.hpp ++++ b/bladeRF_SoapySDR.hpp +@@ -27,6 +27,14 @@ + #include + #include + ++#if defined(LIBBLADERF_API_VERSION) && (LIBBLADERF_API_VERSION >= 0x02000000) ++#define LIBBLADERF_V2 ++#endif ++ ++#ifndef LIBBLADERF_V2 ++typedef unsigned int bladerf_frequency; ++#endif ++ + /*! + * Storage for rx commands and tx responses + */ +@@ -72,15 +80,9 @@ public: + * Channels API + ******************************************************************/ + +- size_t getNumChannels(const int) const +- { +- return 1; +- } ++ size_t getNumChannels(const int) const; + +- bool getFullDuplex(const int, const size_t) const +- { +- return true; +- } ++ bool getFullDuplex(const int, const size_t) const; + + /******************************************************************* + * Stream API +@@ -258,10 +260,17 @@ public: + + private: + +- static bladerf_module _dir2mod(const int direction) ++ #ifndef LIBBLADERF_V2 ++ static bladerf_module _toch(const int direction, const size_t) + { + return (direction == SOAPY_SDR_RX)?BLADERF_MODULE_RX:BLADERF_MODULE_TX; + } ++ #else ++ static bladerf_channel _toch(const int direction, const size_t channel) ++ { ++ return (direction == SOAPY_SDR_RX)?BLADERF_CHANNEL_RX(channel):BLADERF_CHANNEL_TX(channel); ++ } ++ #endif + + static std::string _err2str(const int err) + { +diff --git a/bladeRF_Streaming.cpp b/bladeRF_Streaming.cpp +index 60aca1b..7a0eea0 100644 +--- a/bladeRF_Streaming.cpp ++++ b/bladeRF_Streaming.cpp +@@ -89,14 +89,34 @@ SoapySDR::ArgInfoList bladeRF_SoapySDR::getStreamArgsInfo(const int, const size_ + SoapySDR::Stream *bladeRF_SoapySDR::setupStream( + const int direction, + const std::string &format, +- const std::vector &channels, ++ const std::vector &channels_, + const SoapySDR::Kwargs &args) + { ++ auto channels = channels_; ++ if (channels.empty()) channels.push_back(0); ++ + //check the channel configuration ++ #ifndef LIBBLADERF_V2 + if (channels.size() > 1 or (channels.size() > 0 and channels.at(0) != 0)) + { + throw std::runtime_error("setupStream invalid channel selection"); + } ++ const auto layout = _dir2mod(direction, 0); ++ #else ++ bladerf_channel_layout layout; ++ if (channels.size() == 1 and channels.at(0) == 0) ++ { ++ layout = (direction == SOAPY_SDR_RX)?BLADERF_RX_X1:BLADERF_TX_X1; ++ } ++ else if (channels.size() == 2 and channels.at(0) == 0 and channels.at(1) == 1) ++ { ++ layout = (direction == SOAPY_SDR_RX)?BLADERF_RX_X2:BLADERF_TX_X2; ++ } ++ else ++ { ++ throw std::runtime_error("setupStream invalid channel selection"); ++ } ++ #endif + + //check the format + if (format == "CF32") {} +@@ -122,7 +142,7 @@ SoapySDR::Stream *bladeRF_SoapySDR::setupStream( + //setup the stream for sync tx/rx calls + int ret = bladerf_sync_config( + _dev, +- _dir2mod(direction), ++ layout, + BLADERF_FORMAT_SC16_Q11_META, + numBuffs, + bufSize, +@@ -135,7 +155,7 @@ SoapySDR::Stream *bladeRF_SoapySDR::setupStream( + } + + //activate the stream here -- only call once +- ret = bladerf_enable_module(_dev, _dir2mod(direction), true); ++ ret = bladerf_enable_module(_dev, _toch(direction, 0), true); + if (ret != 0) + { + SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_enable_module(true) returned %d", ret); +@@ -166,7 +186,7 @@ void bladeRF_SoapySDR::closeStream(SoapySDR::Stream *stream) + const int direction = *reinterpret_cast(stream); + + //deactivate the stream here -- only call once +- const int ret = bladerf_enable_module(_dev, _dir2mod(direction), false); ++ const int ret = bladerf_enable_module(_dev, _toch(direction, 0), false); + if (ret != 0) + { + SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_enable_module(false) returned %s", _err2str(ret).c_str()); +@@ -384,7 +404,11 @@ int bladeRF_SoapySDR::writeStream( + else + { + md.flags |= BLADERF_META_FLAG_TX_NOW; ++ #ifndef LIBBLADERF_V2 + bladerf_get_timestamp(_dev, BLADERF_MODULE_TX, &md.timestamp); ++ #else ++ bladerf_get_timestamp(_dev, BLADERF_TX, &md.timestamp); ++ #endif + } + _txNextTicks = md.timestamp; + } diff -Nru soapybladerf-0.3.5/debian/patches/bladerf2-2-62f29cdb643f175f0792ba1bc99332eaddea6f79.patch soapybladerf-0.3.5/debian/patches/bladerf2-2-62f29cdb643f175f0792ba1bc99332eaddea6f79.patch --- soapybladerf-0.3.5/debian/patches/bladerf2-2-62f29cdb643f175f0792ba1bc99332eaddea6f79.patch 1970-01-01 00:00:00.000000000 +0000 +++ soapybladerf-0.3.5/debian/patches/bladerf2-2-62f29cdb643f175f0792ba1bc99332eaddea6f79.patch 2019-09-11 20:35:45.000000000 +0000 @@ -0,0 +1,19 @@ +commit 62f29cdb643f175f0792ba1bc99332eaddea6f79 +Author: Josh Blum +Date: Sat Aug 18 20:53:10 2018 -0500 + + changelog entry for api update + +diff --git a/Changelog.txt b/Changelog.txt +index 145ff53..b7e2922 100644 +--- a/Changelog.txt ++++ b/Changelog.txt +@@ -1,3 +1,8 @@ ++Release 0.4.0 (pending) ++========================== ++ ++- Support for version2 of the libbladerf API ++ + Release 0.3.5 (2018-03-06) + ========================== + diff -Nru soapybladerf-0.3.5/debian/patches/bladerf2-3-c92986eee4535238086203b13d1aa394945d6c21.patch soapybladerf-0.3.5/debian/patches/bladerf2-3-c92986eee4535238086203b13d1aa394945d6c21.patch --- soapybladerf-0.3.5/debian/patches/bladerf2-3-c92986eee4535238086203b13d1aa394945d6c21.patch 1970-01-01 00:00:00.000000000 +0000 +++ soapybladerf-0.3.5/debian/patches/bladerf2-3-c92986eee4535238086203b13d1aa394945d6c21.patch 2019-09-11 20:35:45.000000000 +0000 @@ -0,0 +1,28 @@ +commit c92986eee4535238086203b13d1aa394945d6c21 +Author: Josh Farwell +Date: Fri Aug 17 20:12:12 2018 -0700 + + Set valid sample rate during init + + 1e6 sample rate is out of range for bladerf2, causing + the libbladerf library to throw an error during init. + 4e6 is a friendly value for both bladerf1 and bladerf2 boards. + + Signed-off-by: Josh Farwell + +diff --git a/bladeRF_Settings.cpp b/bladeRF_Settings.cpp +index f2c7be1..179f74e 100644 +--- a/bladeRF_Settings.cpp ++++ b/bladeRF_Settings.cpp +@@ -63,8 +63,9 @@ bladeRF_SoapySDR::bladeRF_SoapySDR(const bladerf_devinfo &devinfo): + if (ret == 0) SoapySDR::logf(SOAPY_SDR_INFO, "bladerf_get_serial() = %s", serialStr); + + //initialize the sample rates to something +- this->setSampleRate(SOAPY_SDR_RX, 0, 1e6); +- this->setSampleRate(SOAPY_SDR_TX, 0, 1e6); ++ this->setSampleRate(SOAPY_SDR_RX, 0, 4e6); ++ this->setSampleRate(SOAPY_SDR_TX, 0, 4e6); ++ + } + + bladeRF_SoapySDR::~bladeRF_SoapySDR(void) diff -Nru soapybladerf-0.3.5/debian/patches/bladerf2-4-6d34c444ffe74ab53d21c9157f0ad0ac83e8316b.patch soapybladerf-0.3.5/debian/patches/bladerf2-4-6d34c444ffe74ab53d21c9157f0ad0ac83e8316b.patch --- soapybladerf-0.3.5/debian/patches/bladerf2-4-6d34c444ffe74ab53d21c9157f0ad0ac83e8316b.patch 1970-01-01 00:00:00.000000000 +0000 +++ soapybladerf-0.3.5/debian/patches/bladerf2-4-6d34c444ffe74ab53d21c9157f0ad0ac83e8316b.patch 2019-09-11 20:35:45.000000000 +0000 @@ -0,0 +1,89 @@ +commit 6d34c444ffe74ab53d21c9157f0ad0ac83e8316b +Author: Josh Farwell +Date: Sat Aug 18 12:02:55 2018 -0700 + + writeSetting: Ask board if loopback mode is valid + + bladerf2 supports different loopback modes than the bladerf1. + version 2 of the library will error out if we pass a loopback mode + struct that is not valid for the attached device. + + If we can, we ask the board if the loopback mode will work, and + log an error if it will not. + + Signed-off-by: Josh Farwell + +diff --git a/bladeRF_Settings.cpp b/bladeRF_Settings.cpp +index 179f74e..ad38878 100644 +--- a/bladeRF_Settings.cpp ++++ b/bladeRF_Settings.cpp +@@ -979,7 +979,11 @@ void bladeRF_SoapySDR::writeSetting(const std::string &key, const std::string &v + else if (key == "loopback") + { + // Verify that a valid setting has arrived +- std::vector loopback_validSettings{ "disabled", "firmware", "bb_txlpf_rxvga2", "bb_txvga1_rxvga2", "bb_txlpf_rxlpf", "bb_txvga1_rxlpf", "rf_lna1", "rf_lna2", "rf_lna3" }; ++ #ifdef LIBBLADERF_V2 ++ std::vector loopback_validSettings{ "disabled", "firmware", "bb_txlpf_rxvga2", "bb_txvga1_rxvga2", "bb_txlpf_rxlpf", "bb_txvga1_rxlpf", "rf_lna1", "rf_lna2", "rf_lna3", "rfic_bist"}; ++ #else ++ std::vector loopback_validSettings{ "disabled", "firmware", "bb_txlpf_rxvga2", "bb_txvga1_rxvga2", "bb_txlpf_rxlpf", "bb_txvga1_rxlpf", "rf_lna1", "rf_lna2", "rf_lna3"}; ++ #endif + if (std::find(std::begin(loopback_validSettings), std::end(loopback_validSettings), value) != std::end(loopback_validSettings)) + { + // --> Valid setting has arrived +@@ -1028,26 +1032,46 @@ void bladeRF_SoapySDR::writeSetting(const std::string &key, const std::string &v + // RF loopback. The TXMIX output, through the AUX PA, is connected to the output of LNA3. + loopback = bladerf_loopback::BLADERF_LB_RF_LNA3; + } ++ #ifdef LIBBLADERF_V2 ++ else if (value == "rfic_bist") ++ { ++ // RF IC Built In Self Test loopback. ++ loopback = bladerf_loopback::BLADERF_LB_RFIC_BIST; ++ } ++ #endif + else + { + // Default: Disabled + // Disables loopback and returns to normal operation + loopback = bladerf_loopback::BLADERF_LB_NONE; + } +- +- // If the loopback isn't already set, set the loopback +- bladerf_loopback _bladerf_loopback = bladerf_loopback::BLADERF_LB_NONE; +- bladerf_get_loopback(_dev, &_bladerf_loopback); +- if (_bladerf_loopback != loopback) ++ #ifdef LIBBLADERF_V2 ++ // Check if the loopback mode is supported by the board ++ if (bladerf_is_loopback_mode_supported(_dev, loopback)) ++ #else ++ if (true) ++ #endif + { +- SoapySDR::logf(SOAPY_SDR_INFO, "bladeRF: Loopback set '%s'", value.c_str()); +- int ret = bladerf_set_loopback(_dev, loopback); +- if (ret != 0) ++ ++ // If the loopback isn't already set, set the loopback ++ bladerf_loopback _bladerf_loopback = bladerf_loopback::BLADERF_LB_NONE; ++ bladerf_get_loopback(_dev, &_bladerf_loopback); ++ if (_bladerf_loopback != loopback) + { +- SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_set_loopback(%s) returned %s", value.c_str(), _err2str(ret).c_str()); +- throw std::runtime_error("writeSetting() " + _err2str(ret)); ++ SoapySDR::logf(SOAPY_SDR_INFO, "bladeRF: Loopback set '%s'", value.c_str()); ++ int ret = bladerf_set_loopback(_dev, loopback); ++ if (ret != 0) ++ { ++ SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_set_loopback(%s) returned %s", value.c_str(), _err2str(ret).c_str()); ++ throw std::runtime_error("writeSetting() " + _err2str(ret)); ++ } + } + } ++ else ++ { ++ // --> Invalid setting has arrived ++ SoapySDR::logf(SOAPY_SDR_ERROR, "bladeRF: Loopback setting '%s' not available on this device.", value.c_str()); ++ } + } + else + { diff -Nru soapybladerf-0.3.5/debian/patches/bladerf2-5-115a7610f9033d6a5cfb578b2440f9a3b233e057.patch soapybladerf-0.3.5/debian/patches/bladerf2-5-115a7610f9033d6a5cfb578b2440f9a3b233e057.patch --- soapybladerf-0.3.5/debian/patches/bladerf2-5-115a7610f9033d6a5cfb578b2440f9a3b233e057.patch 1970-01-01 00:00:00.000000000 +0000 +++ soapybladerf-0.3.5/debian/patches/bladerf2-5-115a7610f9033d6a5cfb578b2440f9a3b233e057.patch 2019-09-11 20:35:45.000000000 +0000 @@ -0,0 +1,24 @@ +commit 115a7610f9033d6a5cfb578b2440f9a3b233e057 +Author: Josh Farwell +Date: Sat Aug 18 12:10:59 2018 -0700 + + Bugfix + + This function changed names, now the build will succeed against + libbladerf-v1 + + Signed-off-by: Josh Farwell + +diff --git a/bladeRF_Streaming.cpp b/bladeRF_Streaming.cpp +index 7a0eea0..9e10f99 100644 +--- a/bladeRF_Streaming.cpp ++++ b/bladeRF_Streaming.cpp +@@ -101,7 +101,7 @@ SoapySDR::Stream *bladeRF_SoapySDR::setupStream( + { + throw std::runtime_error("setupStream invalid channel selection"); + } +- const auto layout = _dir2mod(direction, 0); ++ const auto layout = _toch(direction, 0); + #else + bladerf_channel_layout layout; + if (channels.size() == 1 and channels.at(0) == 0) diff -Nru soapybladerf-0.3.5/debian/patches/bladerf2-6-9f6935745e557f075c017de36e5ff07dc2899fb2.patch soapybladerf-0.3.5/debian/patches/bladerf2-6-9f6935745e557f075c017de36e5ff07dc2899fb2.patch --- soapybladerf-0.3.5/debian/patches/bladerf2-6-9f6935745e557f075c017de36e5ff07dc2899fb2.patch 1970-01-01 00:00:00.000000000 +0000 +++ soapybladerf-0.3.5/debian/patches/bladerf2-6-9f6935745e557f075c017de36e5ff07dc2899fb2.patch 2019-09-11 20:35:45.000000000 +0000 @@ -0,0 +1,56 @@ +commit 9f6935745e557f075c017de36e5ff07dc2899fb2 +Author: Josh Farwell +Date: Sun Aug 19 23:34:39 2018 -0700 + + listGains refactor for libbladerf2 + + we're using new library functionality to get a list of gain stages + that is specific to the connected board. + + Signed-off-by: Josh Farwell + +diff --git a/bladeRF_Settings.cpp b/bladeRF_Settings.cpp +index ad38878..da68cd7 100644 +--- a/bladeRF_Settings.cpp ++++ b/bladeRF_Settings.cpp +@@ -327,10 +327,40 @@ bool bladeRF_SoapySDR::getGainMode(const int direction, const size_t channel) co + + std::vector bladeRF_SoapySDR::listGains(const int direction, const size_t channel) const + { ++ + std::vector options; ++ ++ #ifndef LIBBLADERF_V2 + if (direction == SOAPY_SDR_RX) options.push_back("LNA"); + options.push_back("VGA1"); + options.push_back("VGA2"); ++ ++ #else ++ // Get board version ++ bladerf_fpga_size variant; ++ const int ret = bladerf_get_fpga_size(_dev, &variant); ++ if (ret != 0) ++ { ++ SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_get_fpga_size(%i) returned %s", variant, _err2str(ret)); ++ throw std::runtime_error("listGains() " + _err2str(ret)); ++ } ++ ++ // BladeRF2 ++ if (variant == BLADERF_FPGA_A4 || variant == BLADERF_FPGA_A9) ++ { ++ if (direction == SOAPY_SDR_RX) options.push_back("FULL"); ++ else options.push_back("DSA"); ++ } ++ ++ //BladeRF1 ++ else if (variant == BLADERF_FPGA_115KLE || variant == BLADERF_FPGA_40KLE) ++ { ++ if (direction == SOAPY_SDR_RX) options.push_back("LNA"); ++ options.push_back("VGA1"); ++ options.push_back("VGA2"); ++ } ++ #endif ++ + return options; + } + diff -Nru soapybladerf-0.3.5/debian/patches/bladerf2-7-7df112dc1b4fb206b7c306fcef87b1fd50621641.patch soapybladerf-0.3.5/debian/patches/bladerf2-7-7df112dc1b4fb206b7c306fcef87b1fd50621641.patch --- soapybladerf-0.3.5/debian/patches/bladerf2-7-7df112dc1b4fb206b7c306fcef87b1fd50621641.patch 1970-01-01 00:00:00.000000000 +0000 +++ soapybladerf-0.3.5/debian/patches/bladerf2-7-7df112dc1b4fb206b7c306fcef87b1fd50621641.patch 2019-09-11 20:35:45.000000000 +0000 @@ -0,0 +1,92 @@ +commit 7df112dc1b4fb206b7c306fcef87b1fd50621641 +Author: Josh Farwell +Date: Mon Aug 20 02:50:34 2018 -0700 + + setGain refactor for new API + + Signed-off-by: Josh Farwell + +diff --git a/bladeRF_Settings.cpp b/bladeRF_Settings.cpp +index da68cd7..059d404 100644 +--- a/bladeRF_Settings.cpp ++++ b/bladeRF_Settings.cpp +@@ -341,7 +341,7 @@ std::vector bladeRF_SoapySDR::listGains(const int direction, const + const int ret = bladerf_get_fpga_size(_dev, &variant); + if (ret != 0) + { +- SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_get_fpga_size(%i) returned %s", variant, _err2str(ret)); ++ SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_get_fpga_size(%i) returned %s", variant, _err2str(ret).c_str()); + throw std::runtime_error("listGains() " + _err2str(ret)); + } + +@@ -376,7 +376,13 @@ void bladeRF_SoapySDR::setGain(const int direction, const size_t channel, const + + void bladeRF_SoapySDR::setGain(const int direction, const size_t channel, const std::string &name, const double value) + { ++ // Note: The BladeRF folks do not recommend using this API anymore. ++ // It may be unavailable or have unintended behavior if AGC is turned on. ++ + int ret = 0; ++ ++ #ifndef LIBBLADERF_V2 ++ // Compatibility for bladerf1 + if (direction == SOAPY_SDR_RX and name == "LNA") + { + if (value < 1.5) ret = bladerf_set_lna_gain(_dev, BLADERF_LNA_GAIN_BYPASS); +@@ -387,12 +393,56 @@ void bladeRF_SoapySDR::setGain(const int direction, const size_t channel, const + else if (direction == SOAPY_SDR_RX and name == "VGA2") ret = bladerf_set_rxvga2(_dev, int(value)); + else if (direction == SOAPY_SDR_TX and name == "VGA1") ret = bladerf_set_txvga1(_dev, int(value)); + else if (direction == SOAPY_SDR_TX and name == "VGA2") ret = bladerf_set_txvga2(_dev, int(value)); ++ + else throw std::runtime_error("setGain("+name+") -- unknown name"); + if (ret != 0) + { + SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_set_vga(%f) returned %s", value, _err2str(ret).c_str()); + throw std::runtime_error("setGain("+name+") " + _err2str(ret)); + } ++ ++ #else ++ bladerf_gain _value = (bladerf_gain)value; ++ bladerf_channel _channel = _toch(direction, channel); ++ bladerf_fpga_size variant; ++ ret = bladerf_get_fpga_size(_dev, &variant); ++ ++ if (ret != 0) ++ { ++ SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_get_fpga_size(%i) returned %s", variant, _err2str(ret).c_str()); ++ throw std::runtime_error("setGain() " + _err2str(ret)); ++ } ++ ++ // BladeRF1 Support ++ if (variant == BLADERF_FPGA_115KLE or variant == BLADERF_FPGA_40KLE) ++ { ++ if (direction == SOAPY_SDR_RX and name == "LNA") ++ { ++ if (value < 1.5) ret = bladerf_set_gain_stage(_dev, _channel, "lna", BLADERF_LNA_GAIN_BYPASS); ++ else if (value < 4.5) ret = bladerf_set_gain_stage(_dev, _channel, "lna", BLADERF_LNA_GAIN_MID); ++ else ret = bladerf_set_gain_stage(_dev, _channel, "lna", BLADERF_LNA_GAIN_MAX); ++ } ++ else if (direction == SOAPY_SDR_RX and name == "VGA1") ret = bladerf_set_gain_stage(_dev, _channel, "rxvga1", _value); ++ else if (direction == SOAPY_SDR_RX and name == "VGA2") ret = bladerf_set_gain_stage(_dev, _channel, "rxvga2", _value); ++ else if (direction == SOAPY_SDR_TX and name == "VGA1") ret = bladerf_set_gain_stage(_dev, _channel, "txvga1", _value); ++ else if (direction == SOAPY_SDR_TX and name == "VGA2") ret = bladerf_set_gain_stage(_dev, _channel, "txvga2", _value); ++ else throw std::runtime_error("setGain("+name+") -- unknown name"); ++ } ++ ++ // BladeRF2 Support ++ else if (variant == BLADERF_FPGA_A4 or variant == BLADERF_FPGA_A9) ++ { ++ if (direction == SOAPY_SDR_RX and name == "FULL") ret = bladerf_set_gain_stage(_dev, _channel, "full", _value); ++ else if (direction == SOAPY_SDR_TX and name == "DSA") ret = bladerf_set_gain_stage(_dev, _channel, "dsa", _value); ++ else throw std::runtime_error("setGain("+name+") -- unknown name"); ++ } ++ ++ if (ret != 0) ++ { ++ SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_set_gain_stage(%f) returned %s", value, _err2str(ret).c_str()); ++ throw std::runtime_error("setGain("+name+") " + _err2str(ret)); ++ } ++ #endif + } + + double bladeRF_SoapySDR::getGain(const int direction, const size_t channel, const std::string &name) const diff -Nru soapybladerf-0.3.5/debian/patches/bladerf2-8-ce2ae5444e461e6814bf0d94d182d67a942f6faa.patch soapybladerf-0.3.5/debian/patches/bladerf2-8-ce2ae5444e461e6814bf0d94d182d67a942f6faa.patch --- soapybladerf-0.3.5/debian/patches/bladerf2-8-ce2ae5444e461e6814bf0d94d182d67a942f6faa.patch 1970-01-01 00:00:00.000000000 +0000 +++ soapybladerf-0.3.5/debian/patches/bladerf2-8-ce2ae5444e461e6814bf0d94d182d67a942f6faa.patch 2019-09-11 20:35:46.000000000 +0000 @@ -0,0 +1,121 @@ +commit ce2ae5444e461e6814bf0d94d182d67a942f6faa +Author: Josh Farwell +Date: Mon Aug 20 22:17:41 2018 -0700 + + getGain: libbladerf2 + + Updated for new library API. Also added a getGain method that + gets overall gain for a channel. + + Signed-off-by: Josh Farwell + +diff --git a/bladeRF_Settings.cpp b/bladeRF_Settings.cpp +index 059d404..01e6abe 100644 +--- a/bladeRF_Settings.cpp ++++ b/bladeRF_Settings.cpp +@@ -436,6 +436,7 @@ void bladeRF_SoapySDR::setGain(const int direction, const size_t channel, const + else if (direction == SOAPY_SDR_TX and name == "DSA") ret = bladerf_set_gain_stage(_dev, _channel, "dsa", _value); + else throw std::runtime_error("setGain("+name+") -- unknown name"); + } ++ else throw std::runtime_error("setGain("+name+") -- unknown board type"); + + if (ret != 0) + { +@@ -445,9 +446,22 @@ void bladeRF_SoapySDR::setGain(const int direction, const size_t channel, const + #endif + } + ++double bladeRF_SoapySDR::getGain(const int direction, const size_t channel) const ++{ ++ bladerf_gain gain; ++ const int ret = bladerf_get_gain(_dev, _toch(direction, channel), &gain); ++ if (ret != 0) ++ { ++ SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_get_gain(%zu) returned %s", channel, _err2str(ret).c_str()); ++ throw std::runtime_error("getGain() " + _err2str(ret)); ++ } ++ return (double)gain; ++} ++ + double bladeRF_SoapySDR::getGain(const int direction, const size_t channel, const std::string &name) const + { + int ret = 0; ++ #ifndef LIBBLADERF_V2 + int gain = 0; + if (direction == SOAPY_SDR_RX and name == "LNA") + { +@@ -466,11 +480,61 @@ double bladeRF_SoapySDR::getGain(const int direction, const size_t channel, cons + else if (direction == SOAPY_SDR_TX and name == "VGA1") ret = bladerf_get_txvga1(_dev, &gain); + else if (direction == SOAPY_SDR_TX and name == "VGA2") ret = bladerf_get_txvga2(_dev, &gain); + else throw std::runtime_error("getGain("+name+") -- unknown name"); ++ #else ++ ++ bladerf_gain gain; ++ bladerf_channel _channel = _toch(direction, channel); ++ bladerf_fpga_size variant; ++ ret = bladerf_get_fpga_size(_dev, &variant); ++ ++ if (ret != 0) ++ { ++ SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_get_fpga_size(%i) returned %s", variant, _err2str(ret).c_str()); ++ throw std::runtime_error("setGain() " + _err2str(ret)); ++ } ++ ++ // BladeRF1 Support ++ if (variant == BLADERF_FPGA_115KLE or variant == BLADERF_FPGA_40KLE) ++ { ++ ++ if (direction == SOAPY_SDR_RX and name == "LNA") ++ { ++ ret = bladerf_get_gain_stage(_dev, channel, "lna", &gain); ++ switch (gain) ++ { ++ case BLADERF_LNA_GAIN_UNKNOWN: gain = 0; break; ++ case BLADERF_LNA_GAIN_BYPASS: gain = 0; break; ++ case BLADERF_LNA_GAIN_MID: gain = BLADERF_LNA_GAIN_MID_DB; break; ++ case BLADERF_LNA_GAIN_MAX: gain = BLADERF_LNA_GAIN_MAX_DB; break; ++ } ++ } ++ else if (direction == SOAPY_SDR_RX and name == "VGA1") ret = bladerf_get_gain_stage(_dev, channel, "rxvga1", &gain); ++ else if (direction == SOAPY_SDR_RX and name == "VGA2") ret = bladerf_get_gain_stage(_dev, channel, "rxvga2", &gain); ++ else if (direction == SOAPY_SDR_TX and name == "VGA1") ret = bladerf_get_gain_stage(_dev, channel, "txvga1", &gain); ++ else if (direction == SOAPY_SDR_TX and name == "VGA2") ret = bladerf_get_gain_stage(_dev, channel, "txvga2", &gain); ++ else throw std::runtime_error("getGain("+name+") -- unknown name"); ++ } ++ ++ // BladeRF2 Support ++ else if (variant == BLADERF_FPGA_A4 or variant == BLADERF_FPGA_A9) ++ { ++ if (direction == SOAPY_SDR_RX and name == "FULL") ret = bladerf_get_gain_stage(_dev, _channel, "full", &gain); ++ else if (direction == SOAPY_SDR_TX and name == "DSA") ret = bladerf_get_gain_stage(_dev, _channel, "dsa", &gain); ++ // if (direction == SOAPY_SDR_RX) ret = bladerf_get_gain(_dev, _channel, &gain); ++ // else if (direction == SOAPY_SDR_TX) ret = bladerf_get_gain(_dev, _channel, &gain); ++ else throw std::runtime_error("setGain("+name+") -- unknown name"); ++ } ++ else throw std::runtime_error("setGain("+name+") -- unknown board type"); ++ gain = (double)gain; ++ ++ #endif ++ + if (ret != 0) + { + SoapySDR::logf(SOAPY_SDR_ERROR, "bladerf_get_vga() returned %s", _err2str(ret).c_str()); + throw std::runtime_error("getGain("+name+") " + _err2str(ret)); + } ++ + return gain; + } + +diff --git a/bladeRF_SoapySDR.hpp b/bladeRF_SoapySDR.hpp +index da0a767..6f3b662 100644 +--- a/bladeRF_SoapySDR.hpp ++++ b/bladeRF_SoapySDR.hpp +@@ -180,6 +180,8 @@ public: + + 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; ++ + 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; diff -Nru soapybladerf-0.3.5/debian/patches/bladerf2-9-59aa1e292e1cb74071f48b750ef829694e3d46d7.patch soapybladerf-0.3.5/debian/patches/bladerf2-9-59aa1e292e1cb74071f48b750ef829694e3d46d7.patch --- soapybladerf-0.3.5/debian/patches/bladerf2-9-59aa1e292e1cb74071f48b750ef829694e3d46d7.patch 1970-01-01 00:00:00.000000000 +0000 +++ soapybladerf-0.3.5/debian/patches/bladerf2-9-59aa1e292e1cb74071f48b750ef829694e3d46d7.patch 2019-09-11 20:35:46.000000000 +0000 @@ -0,0 +1,24 @@ +commit 59aa1e292e1cb74071f48b750ef829694e3d46d7 +Author: Josh Farwell +Date: Mon Aug 20 23:15:35 2018 -0700 + + hasGainMode refactor for libbladerf2 + + Signed-off-by: Josh Farwell + +diff --git a/bladeRF_Settings.cpp b/bladeRF_Settings.cpp +index 01e6abe..13db258 100644 +--- a/bladeRF_Settings.cpp ++++ b/bladeRF_Settings.cpp +@@ -284,7 +284,11 @@ std::complex bladeRF_SoapySDR::getIQBalance(const int direction, const s + bool bladeRF_SoapySDR::hasGainMode(const int direction, const size_t channel) const + { + #ifdef HAS_BLADERF_GAIN_MODE ++ # ifndef LIBBLADERF_V2 + return _toch(direction, channel) == BLADERF_MODULE_RX ? true : false; ++ # else ++ return _toch(direction, channel) == BLADERF_CHANNEL_RX(channel) ? true : false; ++ # endif + #else + return false; + #endif diff -Nru soapybladerf-0.3.5/debian/patches/series soapybladerf-0.3.5/debian/patches/series --- soapybladerf-0.3.5/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 +++ soapybladerf-0.3.5/debian/patches/series 2019-09-11 20:36:21.000000000 +0000 @@ -0,0 +1,12 @@ +bladerf2-1-ffca4ab56218c6115c30ecb2cf3a65eeb43e581c.patch +bladerf2-2-62f29cdb643f175f0792ba1bc99332eaddea6f79.patch +bladerf2-3-c92986eee4535238086203b13d1aa394945d6c21.patch +bladerf2-4-6d34c444ffe74ab53d21c9157f0ad0ac83e8316b.patch +bladerf2-5-115a7610f9033d6a5cfb578b2440f9a3b233e057.patch +bladerf2-6-9f6935745e557f075c017de36e5ff07dc2899fb2.patch +bladerf2-7-7df112dc1b4fb206b7c306fcef87b1fd50621641.patch +bladerf2-8-ce2ae5444e461e6814bf0d94d182d67a942f6faa.patch +bladerf2-9-59aa1e292e1cb74071f48b750ef829694e3d46d7.patch +bladerf2-10-641917174c4fc378e7512831a7e5ae01ee2f3a41.patch +bladerf2-11-7cf416b6a187a70ffc6f7491d6c301d1d8b3acf5.patch +bladerf2-12-f7e6007298a2bd2b5d1941a80ca0f384e0f2e49f.patch