diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/fcd/fcd_source.cc | 12 | ||||
-rw-r--r-- | lib/osmosdr/osmosdr_control.cc | 2 | ||||
-rw-r--r-- | lib/osmosdr/osmosdr_src_c.cc | 251 | ||||
-rw-r--r-- | lib/osmosdr/osmosdr_src_c.h | 35 | ||||
-rw-r--r-- | lib/osmosdr_arg_helpers.h | 8 | ||||
-rw-r--r-- | lib/osmosdr_device.cc | 120 | ||||
-rw-r--r-- | lib/osmosdr_source_c_impl.cc | 9 | ||||
-rw-r--r-- | lib/rtl/rtl_source_c.cc | 18 | ||||
-rw-r--r-- | lib/uhd/uhd_source_c.cc | 23 |
10 files changed, 452 insertions, 27 deletions
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 015797f..c9763a7 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -38,6 +38,7 @@ GR_OSMOSDR_APPEND_SRCS( osmosdr_source_c_impl.cc osmosdr_sink_c_impl.cc osmosdr_ranges.cc + osmosdr_device.cc ) GR_OSMOSDR_APPEND_LIBS( diff --git a/lib/fcd/fcd_source.cc b/lib/fcd/fcd_source.cc index fa6caeb..f590388 100644 --- a/lib/fcd/fcd_source.cc +++ b/lib/fcd/fcd_source.cc @@ -38,6 +38,11 @@ fcd_source_sptr make_fcd_source(const std::string &args) return gnuradio::get_initial_sptr(new fcd_source(args)); } +/* + 2 [V10 ]: USB-Audio - FUNcube Dongle V1.0 + Hanlincrest Ltd. FUNcube Dongle V1.0 at usb-0000:00:1d.0-2, full speed + */ + static std::vector< std::string > _get_devices() { std::vector< std::string > devices; @@ -102,8 +107,11 @@ std::vector< std::string > fcd_source::get_devices() int id = 0; std::vector< std::string > devices; - BOOST_FOREACH( std::string dev, _get_devices() ) - devices.push_back( "fcd=" + boost::lexical_cast< std::string >( id++ ) ); + BOOST_FOREACH( std::string dev, _get_devices() ) { + std::string args = "fcd=" + boost::lexical_cast< std::string >( id++ ); + args += ",label='FunCube Dongle'"; + devices.push_back( args ); + } return devices; } diff --git a/lib/osmosdr/osmosdr_control.cc b/lib/osmosdr/osmosdr_control.cc index 4e3f70a..7de2773 100644 --- a/lib/osmosdr/osmosdr_control.cc +++ b/lib/osmosdr/osmosdr_control.cc @@ -45,7 +45,7 @@ osmosdr_control::~osmosdr_control() /* 1 [OsmoSDR ]: USB-Audio - OsmoSDR sysmocom OsmoSDR at usb-0000:00:06.1-2, high speed -*/ + */ std::vector< std::string > osmosdr_control::find_devices() { std::vector< std::string > devices; diff --git a/lib/osmosdr/osmosdr_src_c.cc b/lib/osmosdr/osmosdr_src_c.cc index 9557864..e8181fb 100644 --- a/lib/osmosdr/osmosdr_src_c.cc +++ b/lib/osmosdr/osmosdr_src_c.cc @@ -31,8 +31,12 @@ #include <gr_audio_source.h> #include <gr_float_to_complex.h> +#include <boost/assign.hpp> + #include <osmosdr_arg_helpers.h> +using namespace boost::assign; + /* * Create a new instance of osmosdr_src_c and return * a boost shared_ptr. This is effectively the public constructor. @@ -52,8 +56,30 @@ osmosdr_src_c::osmosdr_src_c (const std::string &args) args_to_io_signature(args)), osmosdr_rx_control(args) { + std::string dev_name; + unsigned int dev_index = 0, mcr = 0; + size_t nchan = 1; + + dict_t dict = params_to_dict(args); + + if (dict.count("osmosdr")) + dev_index = boost::lexical_cast< unsigned int >( dict["osmosdr"] ); + + if (dict.count("mcr")) + mcr = (unsigned int) boost::lexical_cast< double >( dict["mcr"] ); + + if (dict.count("nchan")) + nchan = boost::lexical_cast< size_t >( dict["nchan"] ); + + std::vector< std::string > devices = osmosdr_control::find_devices(); + + if ( devices.size() ) + dev_name = devices[dev_index]; + else + throw std::runtime_error("No OsmoSDR devices found."); + /* Audio source; sample rate is 500kHz by default */ - audio_source::sptr src = audio_make_source(500000, audio_dev_name(), true); + audio_source::sptr src = audio_make_source(500000, dev_name, true); /* block to convert stereo audio to a complex stream */ gr_float_to_complex_sptr f2c = gr_make_float_to_complex(1); @@ -61,6 +87,8 @@ osmosdr_src_c::osmosdr_src_c (const std::string &args) connect(src, 0, f2c, 0); /* Left is I */ connect(src, 1, f2c, 1); /* Right is Q */ connect(f2c, 0, self(), 0); + + _auto_gain = false; } /* @@ -70,3 +98,224 @@ osmosdr_src_c::~osmosdr_src_c () { // nothing else required in this example } + +std::vector<std::string> osmosdr_src_c::get_devices() +{ + int id = 0; + std::vector< std::string > devices; + + BOOST_FOREACH( std::string dev, osmosdr_control::find_devices() ) { + std::string args = "osmosdr=" + boost::lexical_cast< std::string >( id++ ); + args += ",label='sysmocom OsmoSDR'"; + devices.push_back( args ); + } + + return devices; +} + +size_t osmosdr_src_c::get_num_channels() +{ + return 1; +} + +osmosdr::meta_range_t osmosdr_src_c::get_sample_rates() +{ + osmosdr::meta_range_t range; + + range += osmosdr::range_t( 1024000 ); // known to work + range += osmosdr::range_t( 1800000 ); // known to work + range += osmosdr::range_t( 2048000 ); // known to work + range += osmosdr::range_t( 2400000 ); // may work + range += osmosdr::range_t( 2600000 ); // may work + range += osmosdr::range_t( 2800000 ); // may work + range += osmosdr::range_t( 3000000 ); // may work + range += osmosdr::range_t( 3200000 ); // max rate, may work + + // TODO: read from the libosmosdr as soon as the api is available + + return range; +} + +double osmosdr_src_c::set_sample_rate(double rate) +{ +// if (_dev) { +// osmosdr_set_sample_rate( _dev, (uint32_t)rate ); +// } + + return get_sample_rate(); +} + +double osmosdr_src_c::get_sample_rate() +{ +// if (_dev) +// return (double)osmosdr_get_sample_rate( _dev ); + + return 0; +} + +osmosdr::freq_range_t osmosdr_src_c::get_freq_range( size_t chan ) +{ + osmosdr::freq_range_t range; + + range += osmosdr::range_t( 50e6, 2.2e9, 100 ); + + // TODO: read from the libosmosdr as soon as the api is available + + return range; +} + +double osmosdr_src_c::set_center_freq( double freq, size_t chan ) +{ +// if (_dev) +// osmosdr_set_center_freq( _dev, (uint32_t)freq ); + + return get_center_freq( chan ); +} + +double osmosdr_src_c::get_center_freq( size_t chan ) +{ +// if (_dev) +// return (double)osmosdr_get_center_freq( _dev ); + + return 0; +} + +double osmosdr_src_c::set_freq_corr( double ppm, size_t chan ) +{ +// if ( _dev ) +// osmosdr_set_freq_correction( _dev, (int)ppm ); + + return get_freq_corr( chan ); +} + +double osmosdr_src_c::get_freq_corr( size_t chan ) +{ +// if ( _dev ) +// return (double)osmosdr_get_freq_correction( _dev ); + + return 0; +} + +std::vector<std::string> osmosdr_src_c::get_gain_names( size_t chan ) +{ + std::vector< std::string > antennas; + + antennas += "LNA"; + + return antennas; +} + +osmosdr::gain_range_t osmosdr_src_c::get_gain_range( size_t chan ) +{ + osmosdr::gain_range_t range; + + range += osmosdr::range_t( -1.0 ); + range += osmosdr::range_t( 1.5 ); + range += osmosdr::range_t( 4.0 ); + range += osmosdr::range_t( 6.5 ); + range += osmosdr::range_t( 9.0 ); + range += osmosdr::range_t( 11.5 ); + range += osmosdr::range_t( 14.0 ); + range += osmosdr::range_t( 16.5 ); + range += osmosdr::range_t( 19.0 ); + range += osmosdr::range_t( 21.5 ); + range += osmosdr::range_t( 24.0 ); + range += osmosdr::range_t( 29.0 ); + range += osmosdr::range_t( 34.0 ); + range += osmosdr::range_t( 42.0 ); + range += osmosdr::range_t( 43.0 ); + range += osmosdr::range_t( 45.0 ); + range += osmosdr::range_t( 47.0 ); + range += osmosdr::range_t( 49.0 ); + + // TODO: read from the libosmosdr as soon as the api is available + + return range; +} + +osmosdr::gain_range_t osmosdr_src_c::get_gain_range( const std::string & name, size_t chan ) +{ + return get_gain_range( chan ); +} + +bool osmosdr_src_c::set_gain_mode( bool automatic, size_t chan ) +{ +// if (_dev) { +// if (!osmosdr_set_tuner_gain_mode(_dev, int(!automatic))) { +// _auto_gain = automatic; +// } +// } + + return get_gain_mode(chan); +} + +bool osmosdr_src_c::get_gain_mode( size_t chan ) +{ + return _auto_gain; +} + +static double pick_closest_gain(osmosdr::gain_range_t &gains, double required) +{ + double result = required; + double distance = 100; + + BOOST_FOREACH(osmosdr::range_t gain, gains) + { + double diff = fabs(gain.start() - required); + + if (diff < distance) { + distance = diff; + result = gain.start(); + } + } + + return result; +} + +double osmosdr_src_c::set_gain( double gain, size_t chan ) +{ + osmosdr::gain_range_t gains = osmosdr_src_c::get_gain_range( chan ); + double picked_gain = pick_closest_gain( gains, gain ); + +// if (_dev) +// osmosdr_set_tuner_gain( _dev, int(picked_gain * 10.0) ); + + return get_gain( chan ); +} + +double osmosdr_src_c::set_gain( double gain, const std::string & name, size_t chan) +{ + return set_gain( gain, chan ); +} + +double osmosdr_src_c::get_gain( size_t chan ) +{ +// if ( _dev ) +// return ((double)osmosdr_get_tuner_gain( _dev )) / 10.0; + + return 0; +} + +double osmosdr_src_c::get_gain( const std::string & name, size_t chan ) +{ + return get_gain( chan ); +} + +std::vector< std::string > osmosdr_src_c::get_antennas( size_t chan ) +{ + std::vector< std::string > antennas; + + antennas += get_antenna( chan ); + + return antennas; +} + +std::string osmosdr_src_c::set_antenna( const std::string & antenna, size_t chan ) +{ + return get_antenna( chan ); +} + +std::string osmosdr_src_c::get_antenna( size_t chan ) +{ + return "ANT"; +} diff --git a/lib/osmosdr/osmosdr_src_c.h b/lib/osmosdr/osmosdr_src_c.h index de8644b..9a78ce3 100644 --- a/lib/osmosdr/osmosdr_src_c.h +++ b/lib/osmosdr/osmosdr_src_c.h @@ -24,6 +24,8 @@ #include <osmosdr_control.h> #include <gr_hier_block2.h> +#include "osmosdr_src_iface.h" + class osmosdr_src_c; /* @@ -56,7 +58,8 @@ OSMOSDR_API osmosdr_src_c_sptr osmosdr_make_src_c (const std::string & args = "" */ class OSMOSDR_API osmosdr_src_c : public gr_hier_block2, - public osmosdr_rx_control + public osmosdr_rx_control, + public osmosdr_src_iface { private: // The friend declaration allows osmosdr_make_src_c to @@ -72,6 +75,36 @@ private: public: ~osmosdr_src_c (); // public destructor + static std::vector< std::string > get_devices(); + + size_t get_num_channels( void ); + + osmosdr::meta_range_t get_sample_rates( void ); + 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 ); + double set_freq_corr( double ppm, size_t chan = 0 ); + double get_freq_corr( 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 ); + + std::vector< std::string > get_antennas( size_t chan = 0 ); + std::string set_antenna( const std::string & antenna, size_t chan = 0 ); + std::string get_antenna( size_t chan = 0 ); + +private: + bool _auto_gain; }; #endif /* INCLUDED_OSMOSDR_SRC_C_H */ diff --git a/lib/osmosdr_arg_helpers.h b/lib/osmosdr_arg_helpers.h index 85644a2..2261524 100644 --- a/lib/osmosdr_arg_helpers.h +++ b/lib/osmosdr_arg_helpers.h @@ -32,7 +32,7 @@ #include <boost/foreach.hpp> typedef std::map< std::string, std::string > dict_t; -typedef std::pair<std::string, std::string> pair_t; +typedef std::pair< std::string, std::string > pair_t; inline std::vector< std::string > args_to_vector( const std::string &args ) { @@ -88,11 +88,11 @@ inline dict_t params_to_dict( const std::string ¶ms ) std::vector< std::string > param_list = params_to_vector( params ); BOOST_FOREACH(std::string param, param_list) { - pair_t nchan = param_to_pair( param ); - std::string value = nchan.second; + pair_t pair = param_to_pair( param ); + std::string value = pair.second; if (value.length() && value[0] == '\'' && value[ value.length() - 1 ] == '\'') value = value.substr(1, value.length() - 1); - result[ nchan.first ] = nchan.second; + result[ pair.first ] = value; } return result; diff --git a/lib/osmosdr_device.cc b/lib/osmosdr_device.cc new file mode 100644 index 0000000..8efdf39 --- /dev/null +++ b/lib/osmosdr_device.cc @@ -0,0 +1,120 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Dimitri Stolnikov <horiz0n@gmx.net> + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include <osmosdr_device.h> +#include <stdexcept> +#include <boost/foreach.hpp> +#include <boost/thread/mutex.hpp> +#include <algorithm> +#include <sstream> + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +/* +#define ENABLE_OSMOSDR +#define ENABLE_FCD +#define ENABLE_RTL +#define ENABLE_UHD +*/ +#ifdef ENABLE_OSMOSDR +#include <osmosdr_src_c.h> +#endif + +#ifdef ENABLE_FCD +#include <fcd_source.h> +#endif + +#ifdef ENABLE_RTL +#include <rtl_source_c.h> +#endif + +#ifdef ENABLE_UHD +#include <uhd_source_c.h> +#endif + +#include "osmosdr_arg_helpers.h" + +using namespace osmosdr; + +static const std::string args_delim = " "; +static const std::string pairs_delim = ","; +static const std::string pair_delim = "="; + +static boost::mutex _device_mutex; + +device_t::device_t(const std::string &args) +{ + dict_t dict = params_to_dict(args); + + BOOST_FOREACH( dict_t::value_type &entry, dict ) + (*this)[entry.first] = entry.second; +} + +std::string device_t::to_pp_string(void) const +{ + if (this->size() == 0) return "Empty Device Address"; + + std::stringstream ss; + ss << "Device Address:" << std::endl; + BOOST_FOREACH(const device_t::value_type &entry, *this) { + ss << boost::format(" %s: %s") % entry.first % entry.second << std::endl; + } + return ss.str(); +} + +std::string device_t::to_string(void) const +{ + std::stringstream ss; + size_t count = 0; + BOOST_FOREACH(const device_t::value_type &entry, *this) { + std::string value = entry.second; + if (value.find(" ") != std::string::npos) + value = "'" + value + "'"; + ss << ((count++) ? pairs_delim : "") + entry.first + pair_delim + value; + } + return ss.str(); +} + +devices_t device::find(const device_t &hint) +{ + boost::mutex::scoped_lock lock(_device_mutex); + + devices_t devices; + +#ifdef ENABLE_OSMOSDR + BOOST_FOREACH( std::string dev, osmosdr_src_c::get_devices() ) + devices.push_back( device_t(dev) ); +#endif +#ifdef ENABLE_FCD + BOOST_FOREACH( std::string dev, fcd_source::get_devices() ) + devices.push_back( device_t(dev) ); +#endif +#ifdef ENABLE_RTL + BOOST_FOREACH( std::string dev, rtl_source_c::get_devices() ) + devices.push_back( device_t(dev) ); +#endif +#ifdef ENABLE_UHD + BOOST_FOREACH( std::string dev, uhd_source_c::get_devices() ) + devices.push_back( device_t(dev) ); +#endif + + return devices; +} diff --git a/lib/osmosdr_source_c_impl.cc b/lib/osmosdr_source_c_impl.cc index 0c43f74..129701e 100644 --- a/lib/osmosdr_source_c_impl.cc +++ b/lib/osmosdr_source_c_impl.cc @@ -96,7 +96,8 @@ osmosdr_source_c_impl::osmosdr_source_c_impl (const std::string &args) std::vector< std::string > dev_list; #ifdef ENABLE_OSMOSDR - // TODO: implement + BOOST_FOREACH( std::string dev, osmosdr_src_c::get_devices() ) + dev_list.push_back( dev ); #endif #ifdef ENABLE_FCD BOOST_FOREACH( std::string dev, fcd_source::get_devices() ) @@ -133,10 +134,10 @@ osmosdr_source_c_impl::osmosdr_source_c_impl (const std::string &args) if ( dict.count("osmosdr") ) { osmosdr_src_c_sptr src = osmosdr_make_src_c( arg ); -// for (size_t i = 0; i < src->get_num_channels(); i++) -// connect(src, i, self(), channel++); + for (size_t i = 0; i < src->get_num_channels(); i++) + connect(src, i, self(), channel++); -// _devs.push_back( src.get() ); // FIXME: implement interface + _devs.push_back( src.get() ); } #endif diff --git a/lib/rtl/rtl_source_c.cc b/lib/rtl/rtl_source_c.cc index ecb6055..77a5997 100644 --- a/lib/rtl/rtl_source_c.cc +++ b/lib/rtl/rtl_source_c.cc @@ -125,8 +125,8 @@ rtl_source_c::rtl_source_c (const std::string &args) if ( dev_index >= rtlsdr_get_device_count() ) throw std::runtime_error("Wrong rtlsdr device index given."); - std::cerr << "Using device #" << dev_index << " " - << "(" << rtlsdr_get_device_name(dev_index) << ")" + std::cerr << "Using device #" << dev_index << ": " + << rtlsdr_get_device_name(dev_index) << std::endl; _dev = NULL; @@ -173,8 +173,9 @@ rtl_source_c::rtl_source_c (const std::string &args) rtl_source_c::~rtl_source_c () { if (_dev) { + _running = false; rtlsdr_cancel_async( _dev ); - _thread.join(); + _thread.timed_join( boost::posix_time::milliseconds(200) ); rtlsdr_close( _dev ); _dev = NULL; } @@ -294,12 +295,15 @@ int rtl_source_c::work( int noutput_items, std::vector<std::string> rtl_source_c::get_devices() { - std::vector<std::string> result; + std::vector<std::string> devices; - for (unsigned int i = 0; i < rtlsdr_get_device_count(); i++) - result.push_back( "rtl=" + boost::lexical_cast< std::string >( i ) ); + for (unsigned int i = 0; i < rtlsdr_get_device_count(); i++) { + std::string args = "rtl=" + boost::lexical_cast< std::string >( i ); + args += ",label='" + std::string(rtlsdr_get_device_name( i )) + "'"; + devices.push_back( args ); + } - return result; + return devices; } size_t rtl_source_c::get_num_channels() diff --git a/lib/uhd/uhd_source_c.cc b/lib/uhd/uhd_source_c.cc index e930454..958c421 100644 --- a/lib/uhd/uhd_source_c.cc +++ b/lib/uhd/uhd_source_c.cc @@ -41,13 +41,16 @@ uhd_source_c::uhd_source_c(const std::string &args) : gr_make_io_signature (0, 0, 0), args_to_io_signature(args)) { - size_t num_channels = 1; + size_t nchan = 1; std::string arguments = args; dict_t dict = params_to_dict(args); if (dict.count("nchan")) - num_channels = boost::lexical_cast< unsigned int >( dict["nchan"] ); + nchan = boost::lexical_cast< size_t >( dict["nchan"] ); + + if (0 == nchan) + nchan = 1; arguments.clear(); // rebuild argument string without uhd= prefix BOOST_FOREACH( dict_t::value_type &entry, dict ) { @@ -59,12 +62,12 @@ uhd_source_c::uhd_source_c(const std::string &args) : _src = uhd_make_usrp_source( arguments, uhd::io_type_t::COMPLEX_FLOAT32, - num_channels ); + nchan ); if (dict.count("subdev")) _src->set_subdev_spec( dict["subdev"] ); - for ( size_t i = 0; i < num_channels; i++ ) + for ( size_t i = 0; i < nchan; i++ ) connect( _src, i, self(), i ); } @@ -77,8 +80,14 @@ std::vector< std::string > uhd_source_c::get_devices() std::vector< std::string > devices; uhd::device_addr_t hint; - BOOST_FOREACH(uhd::device_addr_t device, uhd::device::find(hint)) - devices += "uhd=" + device.to_string(); + BOOST_FOREACH(const uhd::device_addr_t &dev, uhd::device::find(hint)) { + std::string args = "uhd=," + dev.to_string(); + args += ",label='Ettus USRP'"; + devices.push_back( args ); + } + + //devices.clear(); + //devices.push_back( "uhd=,type=usrp1,label='Ettus USRP'" ); return devices; } @@ -94,7 +103,7 @@ std::string uhd_source_c::name() // std::string dev_name = prop_tree->access<std::string>("/name").get(); std::string mboard_name = _src->get_device()->get_mboard_name(); -// std::cout << "'" << dev_name << "' '" << mboard_name << "'" << std::endl; +// std::cerr << "'" << dev_name << "' '" << mboard_name << "'" << std::endl; // 'USRP1 Device' 'USRP1 (Classic)' // 'B-Series Device' 'B100 (B-Hundo)' |