aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/bladerf/bladerf_common.cc285
-rw-r--r--lib/bladerf/bladerf_common.h31
-rw-r--r--lib/bladerf/bladerf_sink_c.cc136
-rw-r--r--lib/bladerf/bladerf_sink_c.h7
-rw-r--r--lib/bladerf/bladerf_source_c.cc176
-rw-r--r--lib/bladerf/bladerf_source_c.h8
6 files changed, 344 insertions, 299 deletions
diff --git a/lib/bladerf/bladerf_common.cc b/lib/bladerf/bladerf_common.cc
index bb6746a..2b96740 100644
--- a/lib/bladerf/bladerf_common.cc
+++ b/lib/bladerf/bladerf_common.cc
@@ -48,6 +48,10 @@ using namespace boost::assign;
boost::mutex bladerf_common::_devs_mutex;
std::list<boost::weak_ptr<struct bladerf> > bladerf_common::_devs;
+// name of system-wide gain
+//(internal only, doesn't match any libbladeRF gain stage)
+static const char* SYSTEM_GAIN_NAME = "System";
+
bladerf_common::bladerf_common() :
_conv_buf(NULL),
_conv_buf_size(4096),
@@ -105,6 +109,7 @@ bladerf_sptr bladerf_common::open(const std::string &device_name)
int rv;
struct bladerf *raw_dev;
struct bladerf_devinfo devinfo;
+ std::string boardname;
boost::unique_lock<boost::mutex> lock(_devs_mutex);
@@ -127,6 +132,18 @@ bladerf_sptr bladerf_common::open(const std::string &device_name)
_devs.push_back(boost::weak_ptr<struct bladerf>(dev));
+ // TODO: This does NOT get called if early cached_dev return occurs
+ boardname = std::string(bladerf_get_board_name(raw_dev));
+
+ if( "bladerf1" == boardname ) {
+ _boardtype = BLADERF_REV_1;
+ } else if( "bladerf2" == boardname ) {
+ _boardtype = BLADERF_REV_2;
+ } else {
+ std::cerr << "board name \"" << boardname << "\" unknown" << std::endl;
+ _boardtype = BLADERF_REV_INVALID;
+ };
+
return dev;
}
@@ -135,6 +152,7 @@ void bladerf_common::set_loopback_mode(const std::string &loopback)
bladerf_loopback mode;
int status;
+ // TODO: update for bladeRF 2
if (loopback == "bb_txlpf_rxvga2") {
mode = BLADERF_LB_BB_TXLPF_RXVGA2;
} else if (loopback == "bb_txlpf_rxlpf") {
@@ -191,14 +209,30 @@ bool bladerf_common::start(bladerf_module module)
{
int ret;
bladerf_format format;
+ bladerf_channel_layout layout;
+ bladerf_direction direction;
if (_use_metadata) {
- format = BLADERF_FORMAT_SC16_Q11_META;
+ format = BLADERF_FORMAT_SC16_Q11_META;
} else {
- format = BLADERF_FORMAT_SC16_Q11;
+ format = BLADERF_FORMAT_SC16_Q11;
+ }
+
+ // TODO: DRY
+ // TODO: MIMO
+ if (BLADERF_MODULE_RX == module) {
+ layout = BLADERF_RX_X1;
+ direction = BLADERF_RX;
+ } else if (BLADERF_MODULE_TX == module) {
+ layout = BLADERF_TX_X1;
+ direction = BLADERF_TX;
+ } else {
+ std::cerr << _pfx << "invalid module: "
+ << module << std::endl;
+ return false;
}
- ret = bladerf_sync_config(_dev.get(), module, format,
+ ret = bladerf_sync_config(_dev.get(), layout, format,
_num_buffers, _samples_per_buffer,
_num_transfers, _stream_timeout_ms);
@@ -208,7 +242,7 @@ bool bladerf_common::start(bladerf_module module)
return false;
}
- ret = bladerf_enable_module(_dev.get(), module, true);
+ ret = bladerf_enable_module(_dev.get(), direction, true);
if ( ret != 0 ) {
std::cerr << _pfx << "bladerf_enable_module failed: "
<< bladerf_strerror(ret) << std::endl;
@@ -221,8 +255,21 @@ bool bladerf_common::start(bladerf_module module)
bool bladerf_common::stop(bladerf_module module)
{
int ret;
+ bladerf_direction direction;
+
+ // TODO: DRY
+ // TODO: MIMO
+ if (BLADERF_MODULE_RX == module) {
+ direction = BLADERF_RX;
+ } else if (BLADERF_MODULE_TX == module) {
+ direction = BLADERF_TX;
+ } else {
+ std::cerr << _pfx << "invalid module: "
+ << module << std::endl;
+ return false;
+ }
- ret = bladerf_enable_module(_dev.get(), module, false);
+ ret = bladerf_enable_module(_dev.get(), direction, false);
if ( ret != 0 ) {
std::cerr << _pfx << "bladerf_enable_modue failed: "
@@ -491,20 +538,40 @@ void bladerf_common::init(dict_t &dict, bladerf_module module)
}
}
-osmosdr::freq_range_t bladerf_common::freq_range()
+osmosdr::freq_range_t bladerf_common::freq_range(bladerf_channel chan)
{
- /* assuming the same for RX & TX */
- return osmosdr::freq_range_t( _xb_200_attached ? 0 : 280e6, BLADERF_FREQUENCY_MAX );
+ struct bladerf_range brf_range;
+ int ret;
+
+ ret = bladerf_get_frequency_range( _dev.get(), chan, &brf_range );
+
+ if( ret ) {
+ throw std::runtime_error( std::string(__FUNCTION__) + " " +
+ "bladerf_get_frequency_range returned " +
+ boost::lexical_cast<std::string>(ret) );
+ } else {
+ return osmosdr::freq_range_t((double)brf_range.min, (double)brf_range.max, (double)brf_range.step);
+ };
}
osmosdr::meta_range_t bladerf_common::sample_rates()
{
osmosdr::meta_range_t sample_rates;
+ bladerf_range brf_sample_rates;
+ int ret;
/* assuming the same for RX & TX */
- sample_rates += osmosdr::range_t( 160e3, 200e3, 40e3 );
- sample_rates += osmosdr::range_t( 300e3, 900e3, 100e3 );
- sample_rates += osmosdr::range_t( 1e6, 40e6, 1e6 );
+ ret = bladerf_get_sample_rate_range( _dev.get(), BLADERF_CHANNEL_RX(0), &brf_sample_rates );
+
+ if( ret ) {
+ throw std::runtime_error( std::string(__FUNCTION__) + " " +
+ "bladerf_get_sample_rate_range returned " +
+ boost::lexical_cast<std::string>(ret) );
+ }
+
+ sample_rates += osmosdr::range_t( brf_sample_rates.min, brf_sample_rates.max/4.0, brf_sample_rates.max/16.0 );
+ sample_rates += osmosdr::range_t( brf_sample_rates.max/4.0, brf_sample_rates.max/2.0, brf_sample_rates.max/8.0 );
+ sample_rates += osmosdr::range_t( brf_sample_rates.max/2.0, brf_sample_rates.max, brf_sample_rates.max/4.0 );
return sample_rates;
}
@@ -513,14 +580,18 @@ osmosdr::freq_range_t bladerf_common::filter_bandwidths()
{
/* the same for RX & TX according to the datasheet */
osmosdr::freq_range_t bandwidths;
+ bladerf_range brf_range;
+ int ret;
+
+ ret = bladerf_get_bandwidth_range( _dev.get(), BLADERF_CHANNEL_RX(0), &brf_range );
- std::vector<double> half_bandwidths; /* in MHz */
- half_bandwidths += \
- 0.75, 0.875, 1.25, 1.375, 1.5, 1.92, 2.5,
- 2.75, 3, 3.5, 4.375, 5, 6, 7, 10, 14;
+ if( ret ) {
+ throw std::runtime_error( std::string(__FUNCTION__) + " " +
+ "bladerf_get_bandwidth_range returned " +
+ boost::lexical_cast<std::string>(ret) );
+ }
- BOOST_FOREACH( double half_bw, half_bandwidths )
- bandwidths += osmosdr::range_t( half_bw * 2e6 );
+ bandwidths += osmosdr::range_t(brf_range.min, brf_range.max, brf_range.step);
return bandwidths;
}
@@ -560,6 +631,15 @@ std::vector< std::string > bladerf_common::devices()
return ret;
}
+size_t bladerf_common::get_num_channels(bladerf_module module)
+{
+ if (BLADERF_REV_2 == _boardtype) {
+ return 1; // TODO: should be 2 but it ain't working yet
+ } else {
+ return 1;
+ }
+}
+
double bladerf_common::set_sample_rate( bladerf_module module, double rate )
{
int status;
@@ -601,6 +681,177 @@ double bladerf_common::get_sample_rate( bladerf_module module )
return ret;
}
+osmosdr::freq_range_t bladerf_common::get_freq_range( size_t chan )
+{
+ return freq_range((bladerf_channel)chan);
+}
+
+double bladerf_common::set_center_freq( double freq, size_t chan )
+{
+ int ret;
+
+ /* Check frequency range */
+ if( freq < get_freq_range( chan ).start() ||
+ freq > get_freq_range( chan ).stop() ) {
+ std::cerr << "Failed to set out of bound frequency: " << freq << std::endl;
+ } else {
+ ret = bladerf_set_frequency( _dev.get(), (bladerf_channel)chan, (uint64_t)freq );
+ if( ret ) {
+ throw std::runtime_error( std::string(__FUNCTION__) + " " +
+ "failed to set center frequency " +
+ boost::lexical_cast<std::string>(freq) + ": " +
+ std::string(bladerf_strerror(ret)) );
+ }
+ }
+
+ return get_center_freq( chan );
+}
+
+double bladerf_common::get_center_freq( size_t chan )
+{
+ uint64_t freq;
+ int ret;
+
+ ret = bladerf_get_frequency( _dev.get(), (bladerf_channel)chan, &freq );
+ if( ret ) {
+ throw std::runtime_error( std::string(__FUNCTION__) + " " +
+ "failed to get center frequency: " +
+ std::string(bladerf_strerror(ret)) );
+ }
+
+ return (double)freq;
+}
+
+std::vector<std::string> bladerf_common::get_gain_names( size_t chan )
+{
+ const size_t max_count = 16;
+ std::vector< std::string > names;
+ char *gain_names[max_count];
+ int ret;
+
+ memset(&gain_names, 0, sizeof(gain_names));
+
+ names += SYSTEM_GAIN_NAME;
+
+ ret = bladerf_get_gain_stages( _dev.get(), (bladerf_channel)chan, (const char**)&gain_names, max_count);
+
+ if(ret < 0) {
+ throw std::runtime_error( std::string(__FUNCTION__) + " " +
+ "failed to get gain stages: " +
+ std::string(bladerf_strerror(ret)) );
+ }
+
+ for(char **p = gain_names; *p != NULL; ++p) {
+ char *tmp = *p;
+ names += std::string(tmp);
+ };
+
+ return names;
+}
+
+osmosdr::gain_range_t bladerf_common::get_gain_range( size_t chan )
+{
+ /* This is an overall system gain range. */
+ return get_gain_range( SYSTEM_GAIN_NAME, chan );
+}
+
+osmosdr::gain_range_t bladerf_common::get_gain_range( const std::string & name, size_t chan )
+{
+ osmosdr::gain_range_t range;
+ struct bladerf_range brf_range;
+ int ret;
+
+ if( name == SYSTEM_GAIN_NAME ) {
+ ret = bladerf_get_gain_range( _dev.get(), (bladerf_channel)chan, &brf_range );
+ } else {
+ ret = bladerf_get_gain_stage_range( _dev.get(), (bladerf_channel)chan, name.c_str(), &brf_range);
+ }
+
+ if( ret ) {
+ throw std::runtime_error( std::string(__FUNCTION__) + " " +
+ "bladerf_get_gain_range " + name +
+ " error: " +
+ std::string(bladerf_strerror(ret)) );
+ }
+
+ range = osmosdr::gain_range_t( brf_range.min, brf_range.max, brf_range.step );
+
+ return range;
+}
+
+bool bladerf_common::set_gain_mode( bool automatic, size_t chan )
+{
+ return false;
+}
+
+bool bladerf_common::get_gain_mode( size_t chan )
+{
+ return false;
+}
+
+double bladerf_common::set_gain( double gain, size_t chan )
+{
+ return set_gain( gain, SYSTEM_GAIN_NAME, chan );
+}
+
+double bladerf_common::set_gain( double gain, const std::string & name, size_t chan )
+{
+ int ret = 0;
+
+ if( name == SYSTEM_GAIN_NAME ) {
+ ret = bladerf_set_gain( _dev.get(), (bladerf_channel)chan, int(gain) );
+ } else {
+ ret = bladerf_set_gain_stage( _dev.get(), (bladerf_channel)chan, name.c_str(), int(gain) );
+ }
+
+ /* Check for errors */
+ if( ret ) {
+ std::string errmsg = (std::string(__FUNCTION__) + " " +
+ "could not set " + name + " gain: " +
+ std::string(bladerf_strerror(ret)));
+ if ( BLADERF_ERR_UNSUPPORTED == ret ) {
+ // unsupported, but not worth crashing out
+ std::cerr << errmsg << std::endl;
+ } else {
+ throw std::runtime_error(errmsg);
+ }
+ }
+
+ return get_gain( name, chan );
+}
+
+double bladerf_common::get_gain( size_t chan )
+{
+ /* TODO: This is an overall system gain that has to be set */
+ return get_gain( SYSTEM_GAIN_NAME, chan );
+}
+
+double bladerf_common::get_gain( const std::string & name, size_t chan )
+{
+ int g;
+ int ret = 0;
+
+ if( name == SYSTEM_GAIN_NAME ) {
+ ret = bladerf_get_gain( _dev.get(), (bladerf_channel)chan, &g );
+ } else {
+ ret = bladerf_get_gain_stage( _dev.get(), (bladerf_channel)chan, name.c_str(), &g );
+ }
+
+ /* Check for errors */
+ if( ret ) {
+ throw std::runtime_error( std::string(__FUNCTION__) + " " +
+ "could not get " + name + " gain: " +
+ std::string(bladerf_strerror(ret)) );
+ }
+
+ return (double)g;
+}
+
+double bladerf_common::set_bb_gain( double gain, size_t chan )
+{
+ return set_gain( gain, SYSTEM_GAIN_NAME, chan );
+}
+
int bladerf_common::set_dc_offset(bladerf_module module, const std::complex<double> &offset, size_t chan)
{
int ret = 0;
diff --git a/lib/bladerf/bladerf_common.h b/lib/bladerf/bladerf_common.h
index 9c311f7..6c44765 100644
--- a/lib/bladerf/bladerf_common.h
+++ b/lib/bladerf/bladerf_common.h
@@ -55,15 +55,39 @@ public:
virtual ~bladerf_common();
protected:
+ typedef enum {
+ BLADERF_REV_INVALID,
+ BLADERF_REV_1,
+ BLADERF_REV_2
+ } bladerf_boards;
+
/* Handle initialized and parameters common to both source & sink */
void init(dict_t &dict, bladerf_module module);
bool start(bladerf_module module);
bool stop(bladerf_module module);
+ size_t get_num_channels(bladerf_module module);
+
double set_sample_rate(bladerf_module module, double rate);
double get_sample_rate(bladerf_module module);
+ osmosdr::freq_range_t get_freq_range(size_t chan = 0);
+ double set_center_freq(double freq, size_t chan = 0);
+ double get_center_freq(size_t chan = 0);
+
+ std::vector<std::string> get_gain_names( size_t chan = 0 );
+ osmosdr::gain_range_t get_gain_range( size_t chan = 0 );
+ osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 );
+ bool set_gain_mode( bool automatic, size_t chan = 0 );
+ bool get_gain_mode( size_t chan = 0 );
+ double set_gain( double gain, size_t chan = 0 );
+ double set_gain( double gain, const std::string & name, size_t chan = 0 );
+ double get_gain( size_t chan = 0 );
+ double get_gain( const std::string & name, size_t chan = 0 );
+
+ double set_bb_gain( double gain, size_t chan = 0 );
+
int set_dc_offset(bladerf_module module, const std::complex<double> &offset, size_t chan);
int set_iq_balance(bladerf_module module, const std::complex<double> &balance, size_t chan);
@@ -74,7 +98,7 @@ protected:
void set_smb_frequency(double frequency);
double get_smb_frequency();
- osmosdr::freq_range_t freq_range();
+ osmosdr::freq_range_t freq_range(bladerf_channel chan);
osmosdr::meta_range_t sample_rates();
osmosdr::freq_range_t filter_bandwidths();
@@ -82,6 +106,8 @@ protected:
bladerf_sptr _dev;
+ bladerf_boards _boardtype;
+
size_t _num_buffers;
size_t _samples_per_buffer;
size_t _num_transfers;
@@ -92,9 +118,6 @@ protected:
bool _use_metadata;
- osmosdr::gain_range_t _vga1_range;
- osmosdr::gain_range_t _vga2_range;
-
std::string _pfx;
bool _xb_200_attached;
diff --git a/lib/bladerf/bladerf_sink_c.cc b/lib/bladerf/bladerf_sink_c.cc
index 7019629..8f1fc2f 100644
--- a/lib/bladerf/bladerf_sink_c.cc
+++ b/lib/bladerf/bladerf_sink_c.cc
@@ -67,11 +67,11 @@ bladerf_sink_c_sptr make_bladerf_sink_c (const std::string &args)
* (2nd & 3rd args to gr_block's constructor). The input and
* output signatures are used by the runtime system to
* check that a valid number and type of inputs and outputs
- * are connected to this block. In this case, we accept
- * only 0 input and 1 output.
+ * are connected to this block. In this case, we accept either
+ * 1 or 2 inputs.
*/
static const int MIN_IN = 1; // mininum number of input streams
-static const int MAX_IN = 1; // maximum number of input streams
+static const int MAX_IN = 2; // maximum number of input streams
static const int MIN_OUT = 0; // minimum number of output streams
static const int MAX_OUT = 0; // maximum number of output streams
@@ -87,13 +87,6 @@ bladerf_sink_c::bladerf_sink_c (const std::string &args)
/* Perform src/sink agnostic initializations */
init(dict, BLADERF_MODULE_TX);
-
- /* Set the range of VGA1, VGA1GAINT[7:0] */
- _vga1_range = osmosdr::gain_range_t( -35, -4, 1 );
-
- /* Set the range of VGA2, VGA2GAIN[4:0] */
- _vga2_range = osmosdr::gain_range_t( 0, 25, 1 );
-
}
bool bladerf_sink_c::start()
@@ -297,8 +290,7 @@ std::vector<std::string> bladerf_sink_c::get_devices()
size_t bladerf_sink_c::get_num_channels()
{
- /* We only support a single channel for each bladeRF */
- return 1;
+ return bladerf_common::get_num_channels(BLADERF_MODULE_RX);
}
osmosdr::meta_range_t bladerf_sink_c::get_sample_rates()
@@ -316,45 +308,19 @@ double bladerf_sink_c::get_sample_rate()
return bladerf_common::get_sample_rate(BLADERF_MODULE_TX);
}
-osmosdr::freq_range_t bladerf_sink_c::get_freq_range( size_t chan )
+osmosdr::freq_range_t bladerf_sink_c::get_freq_range(size_t chan)
{
- return freq_range();
+ return bladerf_common::get_freq_range(chan);
}
-double bladerf_sink_c::set_center_freq( double freq, size_t chan )
+double bladerf_sink_c::set_center_freq(double freq, size_t chan)
{
- int ret;
-
- /* Check frequency range */
- if( freq < get_freq_range( chan ).start() ||
- freq > get_freq_range( chan ).stop() ) {
- std::cerr << "Failed to set out of bound frequency: " << freq << std::endl;
- } else {
- ret = bladerf_set_frequency( _dev.get(), BLADERF_MODULE_TX, (uint32_t)freq );
- if( ret ) {
- throw std::runtime_error( std::string(__FUNCTION__) + " " +
- "Failed to set center frequency " +
- boost::lexical_cast<std::string>(freq) +
- ":" + std::string(bladerf_strerror(ret)));
- }
- }
-
- return get_center_freq( chan );
+ return bladerf_common::set_center_freq(freq, chan);
}
-double bladerf_sink_c::get_center_freq( size_t chan )
+double bladerf_sink_c::get_center_freq(size_t chan)
{
- uint32_t freq;
- int ret;
-
- ret = bladerf_get_frequency( _dev.get(), BLADERF_MODULE_TX, &freq );
- if( ret ) {
- throw std::runtime_error( std::string(__FUNCTION__) + " " +
- "Failed to get center frequency:" +
- std::string(bladerf_strerror(ret)));
- }
-
- return (double)freq;
+ return bladerf_common::get_center_freq(chan);
}
double bladerf_sink_c::set_freq_corr( double ppm, size_t chan )
@@ -371,114 +337,52 @@ double bladerf_sink_c::get_freq_corr( size_t chan )
std::vector<std::string> bladerf_sink_c::get_gain_names( size_t chan )
{
- std::vector< std::string > names;
-
- names += "VGA1", "VGA2";
-
- return names;
+ return bladerf_common::get_gain_names(chan);
}
osmosdr::gain_range_t bladerf_sink_c::get_gain_range( size_t chan )
{
- /* TODO: This is an overall system gain range. Given the VGA1 and VGA2
- how much total gain can we have in the system */
- return get_gain_range( "VGA2", chan ); /* we use only VGA2 here for now */
+ return bladerf_common::get_gain_range(chan);
}
osmosdr::gain_range_t bladerf_sink_c::get_gain_range( const std::string & name, size_t chan )
{
- osmosdr::gain_range_t range;
-
- if( name == "VGA1" ) {
- range = _vga1_range;
- } else if( name == "VGA2" ) {
- range = _vga2_range;
- } else {
- throw std::runtime_error( std::string(__FUNCTION__) + " " +
- "Requested an invalid gain element " + name );
- }
-
- return range;
+ return bladerf_common::get_gain_range(name, chan);
}
bool bladerf_sink_c::set_gain_mode( bool automatic, size_t chan )
{
- return false;
+ return bladerf_common::set_gain_mode(automatic, chan);
}
bool bladerf_sink_c::get_gain_mode( size_t chan )
{
- return false;
+ return bladerf_common::get_gain_mode(chan);
}
double bladerf_sink_c::set_gain( double gain, size_t chan )
{
- return set_gain( gain, "VGA2", chan ); /* we use only VGA2 here for now */
+ return bladerf_common::set_gain(gain, chan);
}
double bladerf_sink_c::set_gain( double gain, const std::string & name, size_t chan)
{
- int ret = 0;
-
- if( name == "VGA1" ) {
- ret = bladerf_set_txvga1( _dev.get(), (int)gain );
- } else if( name == "VGA2" ) {
- ret = bladerf_set_txvga2( _dev.get(), (int)gain );
- } else {
- throw std::runtime_error( std::string(__FUNCTION__) + " " +
- "Requested to set the gain " +
- "of an unknown gain element " + name );
- }
-
- /* Check for errors */
- if( ret ) {
- throw std::runtime_error(std::string(__FUNCTION__) + " " +
- "Could not set " + name + " gain, error " +
- std::string(bladerf_strerror(ret)));
- }
-
- return get_gain( name, chan );
+ return bladerf_common::set_gain(gain, name, chan);
}
double bladerf_sink_c::get_gain( size_t chan )
{
- return get_gain( "VGA2", chan ); /* we use only VGA2 here for now */
+ return bladerf_common::get_gain(chan);
}
double bladerf_sink_c::get_gain( const std::string & name, size_t chan )
{
- int g;
- int ret = 0;
-
- if( name == "VGA1" ) {
- ret = bladerf_get_txvga1( _dev.get(), &g );
- } else if( name == "VGA2" ) {
- ret = bladerf_get_txvga2( _dev.get(), &g );
- } else {
- throw std::runtime_error( std::string(__FUNCTION__) + " " +
- "Requested to get the gain " +
- "of an unknown gain element " + name );
- }
-
- /* Check for errors */
- if( ret ) {
- throw std::runtime_error( std::string(__FUNCTION__) + " " +
- "Could not get " + name + " gain, error " +
- std::string(bladerf_strerror(ret)));
- }
-
- return (double)g;
+ return bladerf_common::get_gain(name, chan);
}
double bladerf_sink_c::set_bb_gain( double gain, size_t chan )
{
- /* for TX, only VGA1 is in the BB path */
- osmosdr::gain_range_t bb_gains = get_gain_range( "VGA1", chan );
-
- double clip_gain = bb_gains.clip( gain, true );
- gain = set_gain( clip_gain, "VGA1", chan );
-
- return gain;
+ return bladerf_common::set_bb_gain(gain, chan);
}
std::vector< std::string > bladerf_sink_c::get_antennas( size_t chan )
diff --git a/lib/bladerf/bladerf_sink_c.h b/lib/bladerf/bladerf_sink_c.h
index 496abf4..20ed9f7 100644
--- a/lib/bladerf/bladerf_sink_c.h
+++ b/lib/bladerf/bladerf_sink_c.h
@@ -89,9 +89,10 @@ public:
double set_sample_rate( double rate );
double get_sample_rate( void );
- osmosdr::freq_range_t get_freq_range( size_t chan = 0 );
- double set_center_freq( double freq, size_t chan = 0 );
- double get_center_freq( size_t chan = 0 );
+ osmosdr::freq_range_t get_freq_range(size_t chan = 0);
+ double set_center_freq(double freq, size_t chan = 0);
+ double get_center_freq(size_t chan = 0);
+
double set_freq_corr( double ppm, size_t chan = 0 );
double get_freq_corr( size_t chan = 0 );
diff --git a/lib/bladerf/bladerf_source_c.cc b/lib/bladerf/bladerf_source_c.cc
index 17aeacf..042d7ff 100644
--- a/lib/bladerf/bladerf_source_c.cc
+++ b/lib/bladerf/bladerf_source_c.cc
@@ -59,13 +59,13 @@ bladerf_source_c_sptr make_bladerf_source_c (const std::string &args)
* (2nd & 3rd args to gr_block's constructor). The input and
* output signatures are used by the runtime system to
* check that a valid number and type of inputs and outputs
- * are connected to this block. In this case, we accept
- * only 0 input and 1 output.
+ * are connected to this block. In this case, we accept either
+ * 1 or 2 outputs.
*/
static const int MIN_IN = 0; // mininum number of input streams
static const int MAX_IN = 0; // maximum number of input streams
static const int MIN_OUT = 1; // minimum number of output streams
-static const int MAX_OUT = 1; // maximum number of output streams
+static const int MAX_OUT = 2; // maximum number of output streams
/*
* The private constructor
@@ -103,15 +103,6 @@ bladerf_source_c::bladerf_source_c (const std::string &args)
}
}
- /* Set the range of LNA, G_LNA_RXFE[1:0] */
- _lna_range = osmosdr::gain_range_t( 0, 6, 3 );
-
- /* Set the range of VGA1, RFB_TIA_RXFE[6:0], nonlinear mapping done inside the lib */
- _vga1_range = osmosdr::gain_range_t( 5, 30, 1 );
-
- /* Set the range of VGA2 VGA2GAIN[4:0], not recommended to be used above 30dB */
- _vga2_range = osmosdr::gain_range_t( 0, 30, 3 );
-
/* Warn user about using an old FPGA version, as we no longer strip off the
* markers that were pressent in the pre-v0.0.1 FPGA */
if (bladerf_fpga_version( _dev.get(), &fpga_version ) != 0) {
@@ -197,8 +188,7 @@ std::vector<std::string> bladerf_source_c::get_devices()
size_t bladerf_source_c::get_num_channels()
{
- /* We only support a single channel for each bladeRF */
- return 1;
+ return bladerf_common::get_num_channels(BLADERF_MODULE_RX);
}
osmosdr::meta_range_t bladerf_source_c::get_sample_rates()
@@ -216,45 +206,19 @@ double bladerf_source_c::get_sample_rate()
return bladerf_common::get_sample_rate( BLADERF_MODULE_RX );
}
-osmosdr::freq_range_t bladerf_source_c::get_freq_range( size_t chan )
+osmosdr::freq_range_t bladerf_source_c::get_freq_range(size_t chan)
{
- return freq_range();
+ return bladerf_common::get_freq_range(chan);
}
-double bladerf_source_c::set_center_freq( double freq, size_t chan )
+double bladerf_source_c::set_center_freq(double freq, size_t chan)
{
- int ret;
-
- /* Check frequency range */
- if( freq < get_freq_range( chan ).start() ||
- freq > get_freq_range( chan ).stop() ) {
- std::cerr << "Failed to set out of bound frequency: " << freq << std::endl;
- } else {
- ret = bladerf_set_frequency( _dev.get(), BLADERF_MODULE_RX, (uint32_t)freq );
- if( ret ) {
- throw std::runtime_error( std::string(__FUNCTION__) + " " +
- "failed to set center frequency " +
- boost::lexical_cast<std::string>(freq) + ": " +
- std::string(bladerf_strerror(ret)) );
- }
- }
-
- return get_center_freq( chan );
+ return bladerf_common::set_center_freq(freq, chan);
}
-double bladerf_source_c::get_center_freq( size_t chan )
+double bladerf_source_c::get_center_freq(size_t chan)
{
- uint32_t freq;
- int ret;
-
- ret = bladerf_get_frequency( _dev.get(), BLADERF_MODULE_RX, &freq );
- if( ret ) {
- throw std::runtime_error( std::string(__FUNCTION__) + " " +
- "failed to get center frequency: " +
- std::string(bladerf_strerror(ret)) );
- }
-
- return (double)freq;
+ return bladerf_common::get_center_freq(chan);
}
double bladerf_source_c::set_freq_corr( double ppm, size_t chan )
@@ -271,150 +235,52 @@ double bladerf_source_c::get_freq_corr( size_t chan )
std::vector<std::string> bladerf_source_c::get_gain_names( size_t chan )
{
- std::vector< std::string > names;
-
- names += "LNA", "VGA1", "VGA2";
-
- return names;
+ return bladerf_common::get_gain_names(chan);
}
osmosdr::gain_range_t bladerf_source_c::get_gain_range( size_t chan )
{
- /* TODO: This is an overall system gain range. Given the LNA, VGA1 and VGA2
- how much total gain can we have in the system */
- return get_gain_range( "LNA", chan ); /* we use only LNA here for now */
+ return bladerf_common::get_gain_range(chan);
}
osmosdr::gain_range_t bladerf_source_c::get_gain_range( const std::string & name, size_t chan )
{
- osmosdr::gain_range_t range;
-
- if( name == "LNA" ) {
- range = _lna_range;
- } else if( name == "VGA1" ) {
- range = _vga1_range;
- } else if( name == "VGA2" ) {
- range = _vga2_range;
- } else {
- throw std::runtime_error( std::string(__FUNCTION__) + " " +
- "requested an invalid gain element " + name );
- }
-
- return range;
+ return bladerf_common::get_gain_range(name, chan);
}
bool bladerf_source_c::set_gain_mode( bool automatic, size_t chan )
{
- /* TODO: Implement AGC in the FPGA */
- return false;
+ return bladerf_common::set_gain_mode(automatic, chan);
}
bool bladerf_source_c::get_gain_mode( size_t chan )
{
- /* TODO: Read back AGC mode */
- return false;
+ return bladerf_common::get_gain_mode(chan);
}
double bladerf_source_c::set_gain( double gain, size_t chan )
{
- /* TODO: This is an overall system gain that has to be set */
- return set_gain( gain, "LNA", chan ); /* we use only LNA here for now */
+ return bladerf_common::set_gain(gain, chan);
}
-double bladerf_source_c::set_gain( double gain, const std::string & name, size_t chan )
+double bladerf_source_c::set_gain( double gain, const std::string & name, size_t chan)
{
- int ret = 0;
-
- if( name == "LNA" ) {
- bladerf_lna_gain g;
-
- if ( gain >= 6.0f )
- g = BLADERF_LNA_GAIN_MAX;
- else if ( gain >= 3.0f )
- g = BLADERF_LNA_GAIN_MID;
- else /* gain < 3.0f */
- g = BLADERF_LNA_GAIN_BYPASS;
-
- ret = bladerf_set_lna_gain( _dev.get(), g );
- } else if( name == "VGA1" ) {
- ret = bladerf_set_rxvga1( _dev.get(), (int)gain );
- } else if( name == "VGA2" ) {
- ret = bladerf_set_rxvga2( _dev.get(), (int)gain );
- } else {
- throw std::runtime_error( std::string(__FUNCTION__) + " " +
- "requested to set the gain "
- "of an unknown gain element " + name );
- }
-
- /* Check for errors */
- if( ret ) {
- throw std::runtime_error( std::string(__FUNCTION__) + " " +
- "could not set " + name + " gain: " +
- std::string(bladerf_strerror(ret)) );
- }
-
- return get_gain( name, chan );
+ return bladerf_common::set_gain(gain, name, chan);
}
double bladerf_source_c::get_gain( size_t chan )
{
- /* TODO: This is an overall system gain that has to be set */
- return get_gain( "LNA", chan ); /* we use only LNA here for now */
+ return bladerf_common::get_gain(chan);
}
double bladerf_source_c::get_gain( const std::string & name, size_t chan )
{
- int g;
- int ret = 0;
-
- if( name == "LNA" ) {
- bladerf_lna_gain lna_g;
- ret = bladerf_get_lna_gain( _dev.get(), &lna_g );
- g = lna_g == BLADERF_LNA_GAIN_BYPASS ? 0 : lna_g == BLADERF_LNA_GAIN_MID ? 3 : 6;
- } else if( name == "VGA1" ) {
- ret = bladerf_get_rxvga1( _dev.get(), &g );
- } else if( name == "VGA2" ) {
- ret = bladerf_get_rxvga2( _dev.get(), &g );
- } else {
- throw std::runtime_error( std::string(__FUNCTION__) + " " +
- "requested to get the gain "
- "of an unknown gain element " + name );
- }
-
- /* Check for errors */
- if( ret ) {
- throw std::runtime_error( std::string(__FUNCTION__) + " " +
- "could not get " + name + " gain: " +
- std::string(bladerf_strerror(ret)) );
- }
-
- return (double)g;
+ return bladerf_common::get_gain(name, chan);
}
double bladerf_source_c::set_bb_gain( double gain, size_t chan )
{
- osmosdr::gain_range_t vga1_gains = get_gain_range( "VGA1", chan );
- osmosdr::gain_range_t vga2_gains = get_gain_range( "VGA2", chan );
-
- // Gain partitioning from:
- // http://www.limemicro.com/download/FAQ_v1.0r10.pdf part 5.18
-
- // So: first maximize VGA1 gain, then VGA2
-
- if ( gain > vga1_gains.stop() + vga2_gains.start() )
- {
- double clip_gain = vga2_gains.clip( gain - vga1_gains.stop(), true );
-
- gain = set_gain(vga1_gains.stop(), "VGA1", chan) + set_gain(clip_gain, "VGA2", chan);
- }
- else
- {
- double clip_gain = vga1_gains.clip( gain - vga2_gains.start(), true );
-
- gain = set_gain(clip_gain , "VGA1", chan) + set_gain(vga2_gains.start(), "VGA2", chan);
- }
-
- return gain;
+ return bladerf_common::set_bb_gain(gain, chan);
}
std::vector< std::string > bladerf_source_c::get_antennas( size_t chan )
diff --git a/lib/bladerf/bladerf_source_c.h b/lib/bladerf/bladerf_source_c.h
index 131b5ed..d7e8ad5 100644
--- a/lib/bladerf/bladerf_source_c.h
+++ b/lib/bladerf/bladerf_source_c.h
@@ -81,9 +81,10 @@ public:
double set_sample_rate( double rate );
double get_sample_rate( void );
- osmosdr::freq_range_t get_freq_range( size_t chan = 0 );
- double set_center_freq( double freq, size_t chan = 0 );
- double get_center_freq( size_t chan = 0 );
+ osmosdr::freq_range_t get_freq_range(size_t chan = 0);
+ double set_center_freq(double freq, size_t chan = 0);
+ double get_center_freq(size_t chan = 0);
+
double set_freq_corr( double ppm, size_t chan = 0 );
double get_freq_corr( size_t chan = 0 );
@@ -118,7 +119,6 @@ public:
std::vector<std::string> get_clock_sources(const size_t mboard);
private:
- osmosdr::gain_range_t _lna_range;
};
#endif /* INCLUDED_BLADERF_SOURCE_C_H */