diff --git a/lib/bladerf/bladerf_sink_c.cc b/lib/bladerf/bladerf_sink_c.cc index 24d1842..732c946 100644 --- a/lib/bladerf/bladerf_sink_c.cc +++ b/lib/bladerf/bladerf_sink_c.cc @@ -35,6 +35,7 @@ #include #include +#include #include #include "osmosdr_arg_helpers.h" @@ -73,8 +74,6 @@ bladerf_sink_c::bladerf_sink_c (const std::string &args) gr_make_io_signature (MIN_IN, MAX_IN, sizeof (gr_complex)), gr_make_io_signature (MIN_OUT, MAX_OUT, sizeof (gr_complex))) { - int ret; - dict_t dict = params_to_dict(args); /* Perform src/sink agnostic initializations */ @@ -86,36 +85,11 @@ bladerf_sink_c::bladerf_sink_c (const std::string &args) /* Set the range of VGA2, VGA2GAIN[4:0] */ _vga2_range = osmosdr::gain_range_t( 0, 25, 1 ); - /* Initialize the stream */ - ret = bladerf_init_stream( &_stream, _dev.get(), stream_callback, - &_buffers, _num_buffers, BLADERF_FORMAT_SC16_Q12, - _samples_per_buffer, _num_transfers, this ); - if ( ret != 0 ) - std::cerr << _pfx << "bladerf_init_stream failed:" - << bladerf_strerror(ret) << std::endl; - - /* Initialize buffer management */ - _buf_index = _next_to_tx = 0; - _next_value = static_cast(_buffers[0]); - _samples_left = _samples_per_buffer; - _filled = new bool[_num_buffers]; if (!_filled) { throw std::runtime_error( std::string(__FUNCTION__) + " " + "Failed to allocate _filled[]" ); } - - for (size_t i = 0; i < _num_buffers; ++i) { - _filled[i] = false; - } - - ret = bladerf_enable_module( _dev.get(), BLADERF_MODULE_TX, true ); - if ( ret != 0 ) - std::cerr << _pfx << "bladerf_enable_module has failed:" - << bladerf_strerror(ret) << std::endl; - - set_running( true ); - _thread = gruel::thread( boost::bind(&bladerf_sink_c::write_task, this) ); } /* @@ -125,15 +99,11 @@ bladerf_sink_c::~bladerf_sink_c () { int ret; - set_running(false); - - /* Ensure work() or callbacks return from wait() calls */ - _buf_status_lock.lock(); - _buffer_filled.notify_all(); - _buffer_emptied.notify_all(); - _buf_status_lock.unlock(); - - _thread.join(); + if( is_running() == true ) { + std::cerr << _pfx << "Still running when destructor called!" + << std::endl; + stop(); + } ret = bladerf_enable_module( _dev.get(), BLADERF_MODULE_TX, false ); if ( ret != 0 ) @@ -206,20 +176,63 @@ void bladerf_sink_c::write_task() int status; /* Start stream and stay there until we kill the stream */ + set_running(true); status = bladerf_stream(_stream, BLADERF_MODULE_TX); if ( status < 0 ) { - std::cerr << _pfx << "Sink stream error: " - << bladerf_strerror(status) << std::endl; + set_running(false); + std::cerr << _pfx << "Sink stream error: " + << bladerf_strerror(status) << std::endl; - if ( status == BLADERF_ERR_TIMEOUT ) { - std::cerr << _pfx << "Try adjusting your sample rate or the " - << "\"buffers\", \"buflen\", and \"transfers\" parameters. " - << std::endl; - } + if ( status == BLADERF_ERR_TIMEOUT ) { + std::cerr << _pfx << "Try adjusting your sample rate or the " + << "\"buffers\", \"buflen\", and \"transfers\" parameters. " + << std::endl; + } + } +} + +bool bladerf_sink_c::start() +{ + int ret; + + /* Initialize the stream */ + ret = bladerf_init_stream( &_stream, _dev.get(), stream_callback, + &_buffers, _num_buffers, BLADERF_FORMAT_SC16_Q12, + _samples_per_buffer, _num_transfers, this ); + if ( ret != 0 ) { + throw std::runtime_error( std::string(__FUNCTION__) + " " + + "bladerf_init_stream failed" ) ; } - set_running( false ); + /* Initialize buffer management */ + _buf_index = _next_to_tx = 0; + _next_value = static_cast(_buffers[0]); + _samples_left = _samples_per_buffer; + + for (size_t i = 0; i < _num_buffers; ++i) { + _filled[i] = false; + } + + ret = bladerf_enable_module( _dev.get(), BLADERF_MODULE_TX, true ); + if ( ret != 0 ) { + throw std::runtime_error(std::string(__FUNCTION__) + " " + + "bladerf_enable_module has failed:" + bladerf_strerror(ret) ); + } + + _thread = gruel::thread( boost::bind(&bladerf_sink_c::write_task, this) ); + while(is_running() == false) { + /* Not quite started up just yet, so wait for a short period of time */ + boost::this_thread::sleep( boost::posix_time::milliseconds(1) ); + } + return true; +} + +bool bladerf_sink_c::stop() +{ + set_running(false); + _thread.join(); + return true; } int bladerf_sink_c::work( int noutput_items, @@ -550,7 +563,7 @@ void bladerf_sink_c::set_iq_balance( const std::complex &balance, size_t int ret = 0; int16_t val_gain,val_phase; - //FPGA gain correction defines 0.0 as BLADERF_GAIN_ZERO, scale the offset range to +/- BLADERF_GAIN_RANGE + //FPGA gain correction defines 0.0 as BLADERF_GAIN_ZERO, scale the offset range to +/- BLADERF_GAIN_RANGE val_gain = (int16_t)(balance.real() * (int16_t)BLADERF_GAIN_RANGE) + BLADERF_GAIN_ZERO; //FPGA phase correction steps from -45 to 45 degrees val_phase = (int16_t)(balance.imag() * BLADERF_PHASE_RANGE); diff --git a/lib/bladerf/bladerf_sink_c.h b/lib/bladerf/bladerf_sink_c.h index 628ce77..09c122b 100644 --- a/lib/bladerf/bladerf_sink_c.h +++ b/lib/bladerf/bladerf_sink_c.h @@ -69,6 +69,9 @@ private: public: ~bladerf_sink_c (); // public destructor + bool start(); + bool stop(); + int work( int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items ); diff --git a/lib/bladerf/bladerf_source_c.cc b/lib/bladerf/bladerf_source_c.cc index 229edab..136565d 100644 --- a/lib/bladerf/bladerf_source_c.cc +++ b/lib/bladerf/bladerf_source_c.cc @@ -35,11 +35,12 @@ #include #include +#include #include #include "osmosdr_arg_helpers.h" #include "bladerf_source_c.h" -#include "osmosdr/source.h" +#include "osmosdr/osmosdr_source_c.h" /* * Default size of sample FIFO, in entries. @@ -139,22 +140,6 @@ bladerf_source_c::bladerf_source_c (const std::string &args) /* Set the range of VGA2 VGA2GAIN[4:0], not recommended to be used above 30dB */ _vga2_range = osmosdr::gain_range_t( 0, 60, 3 ); - - /* Initialize the stream */ - _buf_index = 0; - ret = bladerf_init_stream( &_stream, _dev.get(), stream_callback, - &_buffers, _num_buffers, BLADERF_FORMAT_SC16_Q12, - _samples_per_buffer, _num_buffers, this ); - if ( ret != 0 ) - std::cerr << _pfx << "bladerf_init_stream failed: " - << bladerf_strerror(ret) << std::endl; - - ret = bladerf_enable_module( _dev.get(), BLADERF_MODULE_RX, true ); - if ( ret != 0 ) - std::cerr << _pfx << "bladerf_enable_module failed:" - << bladerf_strerror(ret) << std::endl; - - _thread = gruel::thread( boost::bind(&bladerf_source_c::read_task, this) ); } /* @@ -164,8 +149,11 @@ bladerf_source_c::~bladerf_source_c () { int ret; - set_running(false); - _thread.join(); + if (is_running()) { + std::cerr << _pfx << "Still running when destructor called!" + << std::endl; + stop(); + } ret = bladerf_enable_module( _dev.get(), BLADERF_MODULE_RX, false ); if ( ret != 0 ) @@ -250,16 +238,49 @@ void bladerf_source_c::read_task() status = bladerf_stream(_stream, BLADERF_MODULE_RX); if ( status < 0 ) { - std::cerr << "Source stream error: " << bladerf_strerror(status) << std::endl; + set_running( false ); + std::cerr << "Source stream error: " << bladerf_strerror(status) << std::endl; - if ( status == BLADERF_ERR_TIMEOUT ) { - std::cerr << _pfx << "Try adjusting your sample rate or the " - << "\"buffers\", \"buflen\", and \"transfers\" parameters. " - << std::endl; - } + if ( status == BLADERF_ERR_TIMEOUT ) { + std::cerr << _pfx << "Try adjusting your sample rate or the " + << "\"buffers\", \"buflen\", and \"transfers\" parameters. " + << std::endl; + } + } +} + +bool bladerf_source_c::start() +{ + int ret; + + /* Initialize the stream */ + _buf_index = 0; + ret = bladerf_init_stream( &_stream, _dev.get(), stream_callback, + &_buffers, _num_buffers, BLADERF_FORMAT_SC16_Q12, + _samples_per_buffer, _num_buffers, this ); + if ( ret != 0 ) + std::cerr << _pfx << "bladerf_init_stream failed: " + << bladerf_strerror(ret) << std::endl; + + ret = bladerf_enable_module( _dev.get(), BLADERF_MODULE_RX, true ); + if ( ret != 0 ) + std::cerr << _pfx << "bladerf_enable_module failed:" + << bladerf_strerror(ret) << std::endl; + + _thread = gruel::thread( boost::bind(&bladerf_source_c::read_task, this) ); + + while( is_running() == false ) { + boost::this_thread::sleep( boost::posix_time::milliseconds(1) ); } - set_running( false ); + return true; +} + +bool bladerf_source_c::stop() +{ + set_running(false); + _thread.join(); + return true; } /* Main work function, pull samples from the sample fifo */ @@ -287,8 +308,6 @@ int bladerf_source_c::work( int noutput_items, out[i] = _fifo->at(0); _fifo->pop_front(); } - - //std::cerr << "-" << std::flush; } return noutput_items; @@ -314,7 +333,6 @@ double bladerf_source_c::set_sample_rate( double rate ) { int ret; uint32_t actual; - /* Set the Si5338 to be 2x this sample rate */ /* Check to see if the sample rate is an integer */ if( (uint32_t)round(rate) == (uint32_t)rate ) @@ -561,12 +579,12 @@ std::string bladerf_source_c::get_antenna( size_t chan ) void bladerf_source_c::set_dc_offset_mode( int mode, size_t chan ) { - if ( osmosdr::source::DCOffsetOff == mode ) { + if ( osmosdr_source_c::DCOffsetOff == mode ) { //_src->set_auto_dc_offset( false, chan ); set_dc_offset( std::complex(0.0, 0.0), chan ); /* reset to default for off-state */ - } else if ( osmosdr::source::DCOffsetManual == mode ) { + } else if ( osmosdr_source_c::DCOffsetManual == mode ) { //_src->set_auto_dc_offset( false, chan ); /* disable auto mode, but keep correcting with last known values */ - } else if ( osmosdr::source::DCOffsetAutomatic == mode ) { + } else if ( osmosdr_source_c::DCOffsetAutomatic == mode ) { //_src->set_auto_dc_offset( true, chan ); std::cerr << "Automatic DC correction mode is not implemented." << std::endl; } @@ -597,12 +615,12 @@ void bladerf_source_c::set_dc_offset( const std::complex &offset, size_t void bladerf_source_c::set_iq_balance_mode( int mode, size_t chan ) { - if ( osmosdr::source::IQBalanceOff == mode ) { + if ( osmosdr_source_c::IQBalanceOff == mode ) { //_src->set_auto_iq_balance( false, chan ); set_iq_balance( std::complex(0.0, 0.0), chan ); /* reset to default for off-state */ - } else if ( osmosdr::source::IQBalanceManual == mode ) { + } else if ( osmosdr_source_c::IQBalanceManual == mode ) { //_src->set_auto_iq_balance( false, chan ); /* disable auto mode, but keep correcting with last known values */ - } else if ( osmosdr::source::IQBalanceAutomatic == mode ) { + } else if ( osmosdr_source_c::IQBalanceAutomatic == mode ) { //_src->set_auto_iq_balance( true, chan ); std::cerr << "Automatic IQ correction mode is not implemented." << std::endl; } @@ -613,7 +631,7 @@ void bladerf_source_c::set_iq_balance( const std::complex &balance, size int ret = 0; int16_t val_gain,val_phase; - //FPGA gain correction defines 0.0 as BLADERF_GAIN_ZERO, scale the offset range to +/- BLADERF_GAIN_RANGE + //FPGA gain correction defines 0.0 as BLADERF_GAIN_ZERO, scale the offset range to +/- BLADERF_GAIN_RANGE val_gain = (int16_t)(balance.real() * (int16_t)BLADERF_GAIN_RANGE) + BLADERF_GAIN_ZERO; //FPGA phase correction steps from -45 to 45 degrees val_phase = (int16_t)(balance.imag() * BLADERF_PHASE_RANGE); diff --git a/lib/bladerf/bladerf_source_c.h b/lib/bladerf/bladerf_source_c.h index 5020b41..bbbff69 100644 --- a/lib/bladerf/bladerf_source_c.h +++ b/lib/bladerf/bladerf_source_c.h @@ -69,6 +69,9 @@ private: public: ~bladerf_source_c (); // public destructor + bool start(); + bool stop(); + int work( int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items );