diff options
Diffstat (limited to 'gr-uhd/lib/gr_uhd_usrp_sink.cc')
-rw-r--r-- | gr-uhd/lib/gr_uhd_usrp_sink.cc | 169 |
1 files changed, 157 insertions, 12 deletions
diff --git a/gr-uhd/lib/gr_uhd_usrp_sink.cc b/gr-uhd/lib/gr_uhd_usrp_sink.cc index 1a6595293..05237100c 100644 --- a/gr-uhd/lib/gr_uhd_usrp_sink.cc +++ b/gr-uhd/lib/gr_uhd_usrp_sink.cc @@ -22,11 +22,25 @@ #include <gr_uhd_usrp_sink.h> #include <gr_io_signature.h> #include <stdexcept> +#include <boost/make_shared.hpp> static const pmt::pmt_t SOB_KEY = pmt::pmt_string_to_symbol("tx_sob"); static const pmt::pmt_t EOB_KEY = pmt::pmt_string_to_symbol("tx_eob"); static const pmt::pmt_t TIME_KEY = pmt::pmt_string_to_symbol("tx_time"); +#include <uhd/convert.hpp> +inline gr_io_signature_sptr args_to_io_sig(const uhd::stream_args_t &args){ + const size_t nchan = std::max<size_t>(args.channels.size(), 1); + #ifdef GR_UHD_USE_STREAM_API + const size_t size = uhd::convert::get_bytes_per_item(args.cpu_format); + #else + size_t size = 0; + if (args.cpu_format == "fc32") size = 8; + if (args.cpu_format == "sc16") size = 4; + #endif + return gr_make_io_signature(nchan, nchan, size); +} + /*********************************************************************** * UHD Multi USRP Sink Impl **********************************************************************/ @@ -34,17 +48,18 @@ class uhd_usrp_sink_impl : public uhd_usrp_sink{ public: uhd_usrp_sink_impl( const uhd::device_addr_t &device_addr, - const uhd::io_type_t &io_type, - size_t num_channels + const uhd::stream_args_t &stream_args ): gr_sync_block( "gr uhd usrp sink", - gr_make_io_signature(num_channels, num_channels, io_type.size), + args_to_io_sig(stream_args), gr_make_io_signature(0, 0, 0) ), - _type(io_type), - _nchan(num_channels) + _stream_args(stream_args), + _nchan(std::max<size_t>(1, stream_args.channels.size())) { + if (stream_args.cpu_format == "fc32") _type = boost::make_shared<uhd::io_type_t>(uhd::io_type_t::COMPLEX_FLOAT32); + if (stream_args.cpu_format == "sc16") _type = boost::make_shared<uhd::io_type_t>(uhd::io_type_t::COMPLEX_INT16); _dev = uhd::usrp::multi_usrp::make(device_addr); } @@ -61,6 +76,14 @@ public: return _dev->get_tx_rate(); } + uhd::meta_range_t get_samp_rates(void){ + #ifdef UHD_USRP_MULTI_USRP_GET_RATES_API + return _dev->get_tx_rates(); + #else + throw std::runtime_error("not implemented in this version"); + #endif + } + uhd::tune_result_t set_center_freq( const uhd::tune_request_t tune_request, size_t chan ){ @@ -119,11 +142,27 @@ public: return _dev->set_tx_bandwidth(bandwidth, chan); } - uhd::sensor_value_t get_dboard_sensor(const std::string &name, size_t chan){ + void set_dc_offset(const std::complex<double> &offset, size_t chan){ + #ifdef UHD_USRP_MULTI_USRP_FRONTEND_CAL_API + return _dev->set_tx_dc_offset(offset, chan); + #else + throw std::runtime_error("not implemented in this version"); + #endif + } + + void set_iq_balance(const std::complex<double> &correction, size_t chan){ + #ifdef UHD_USRP_MULTI_USRP_FRONTEND_CAL_API + return _dev->set_tx_iq_balance(correction, chan); + #else + throw std::runtime_error("not implemented in this version"); + #endif + } + + uhd::sensor_value_t get_sensor(const std::string &name, size_t chan){ return _dev->get_tx_sensor(name, chan); } - std::vector<std::string> get_dboard_sensor_names(size_t chan){ + std::vector<std::string> get_sensor_names(size_t chan){ return _dev->get_tx_sensor_names(chan); } @@ -139,6 +178,54 @@ public: return _dev->set_clock_config(clock_config, mboard); } + void set_time_source(const std::string &source, const size_t mboard){ + #ifdef UHD_USRP_MULTI_USRP_REF_SOURCES_API + return _dev->set_time_source(source, mboard); + #else + throw std::runtime_error("not implemented in this version"); + #endif + } + + std::string get_time_source(const size_t mboard){ + #ifdef UHD_USRP_MULTI_USRP_REF_SOURCES_API + return _dev->get_time_source(mboard); + #else + throw std::runtime_error("not implemented in this version"); + #endif + } + + std::vector<std::string> get_time_sources(const size_t mboard){ + #ifdef UHD_USRP_MULTI_USRP_REF_SOURCES_API + return _dev->get_time_sources(mboard); + #else + throw std::runtime_error("not implemented in this version"); + #endif + } + + void set_clock_source(const std::string &source, const size_t mboard){ + #ifdef UHD_USRP_MULTI_USRP_REF_SOURCES_API + return _dev->set_clock_source(source, mboard); + #else + throw std::runtime_error("not implemented in this version"); + #endif + } + + std::string get_clock_source(const size_t mboard){ + #ifdef UHD_USRP_MULTI_USRP_REF_SOURCES_API + return _dev->get_clock_source(mboard); + #else + throw std::runtime_error("not implemented in this version"); + #endif + } + + std::vector<std::string> get_clock_sources(const size_t mboard){ + #ifdef UHD_USRP_MULTI_USRP_REF_SOURCES_API + return _dev->get_clock_sources(mboard); + #else + throw std::runtime_error("not implemented in this version"); + #endif + } + double get_clock_rate(size_t mboard){ return _dev->get_master_clock_rate(mboard); } @@ -167,6 +254,22 @@ public: return _dev->set_time_unknown_pps(time_spec); } + void set_command_time(const uhd::time_spec_t &time_spec, size_t mboard){ + #ifdef UHD_USRP_MULTI_USRP_COMMAND_TIME_API + return _dev->set_command_time(time_spec, mboard); + #else + throw std::runtime_error("not implemented in this version"); + #endif + } + + void clear_command_time(size_t mboard){ + #ifdef UHD_USRP_MULTI_USRP_COMMAND_TIME_API + return _dev->clear_command_time(mboard); + #else + throw std::runtime_error("not implemented in this version"); + #endif + } + uhd::usrp::dboard_iface::sptr get_dboard_iface(size_t chan){ return _dev->get_tx_dboard_iface(chan); } @@ -194,11 +297,17 @@ public: get_tags_in_range(_tags, 0, samp0_count, samp0_count + ninput_items); if (not _tags.empty()) this->tag_work(ninput_items); + #ifdef GR_UHD_USE_STREAM_API //send all ninput_items with metadata + const size_t num_sent = _tx_stream->send( + input_items, ninput_items, _metadata, 1.0 + ); + #else const size_t num_sent = _dev->get_device()->send( input_items, ninput_items, _metadata, - _type, uhd::device::SEND_MODE_FULL_BUFF, 1.0 + *_type, uhd::device::SEND_MODE_FULL_BUFF, 1.0 ); + #endif //increment the timespec by the number of samples sent _metadata.time_spec += uhd::time_spec_t(0, num_sent, _sample_rate); @@ -266,15 +375,25 @@ public: //Send an empty start-of-burst packet to begin streaming. //Set at a time in the near future to avoid late packets. bool start(void){ + #ifdef GR_UHD_USE_STREAM_API + _tx_stream = _dev->get_tx_stream(_stream_args); + #endif + _metadata.start_of_burst = true; _metadata.end_of_burst = false; _metadata.has_time_spec = _nchan > 1; _metadata.time_spec = get_time_now() + uhd::time_spec_t(0.01); + #ifdef GR_UHD_USE_STREAM_API + _tx_stream->send( + gr_vector_const_void_star(_nchan), 0, _metadata, 1.0 + ); + #else _dev->get_device()->send( gr_vector_const_void_star(_nchan), 0, _metadata, - _type, uhd::device::SEND_MODE_ONE_PACKET, 1.0 + *_type, uhd::device::SEND_MODE_ONE_PACKET, 1.0 ); + #endif return true; } @@ -285,16 +404,24 @@ public: _metadata.end_of_burst = true; _metadata.has_time_spec = false; + #ifdef GR_UHD_USE_STREAM_API + _tx_stream->send(gr_vector_const_void_star(_nchan), 0, _metadata, 1.0); + #else _dev->get_device()->send( gr_vector_const_void_star(_nchan), 0, _metadata, - _type, uhd::device::SEND_MODE_ONE_PACKET, 1.0 + *_type, uhd::device::SEND_MODE_ONE_PACKET, 1.0 ); + #endif return true; } private: uhd::usrp::multi_usrp::sptr _dev; - const uhd::io_type_t _type; + const uhd::stream_args_t _stream_args; + boost::shared_ptr<uhd::io_type_t> _type; + #ifdef GR_UHD_USE_STREAM_API + uhd::tx_streamer::sptr _tx_stream; + #endif size_t _nchan; uhd::tx_metadata_t _metadata; double _sample_rate; @@ -311,7 +438,25 @@ boost::shared_ptr<uhd_usrp_sink> uhd_make_usrp_sink( const uhd::io_type_t &io_type, size_t num_channels ){ + //fill in the streamer args + uhd::stream_args_t stream_args; + switch(io_type.tid){ + case uhd::io_type_t::COMPLEX_FLOAT32: stream_args.cpu_format = "fc32"; break; + case uhd::io_type_t::COMPLEX_INT16: stream_args.cpu_format = "sc16"; break; + default: throw std::runtime_error("only complex float and shorts known to work"); + } + stream_args.otw_format = "sc16"; //only sc16 known to work + for (size_t chan = 0; chan < num_channels; chan++) + stream_args.channels.push_back(chan); //linear mapping + + return uhd_make_usrp_sink(device_addr, stream_args); +} + +boost::shared_ptr<uhd_usrp_sink> uhd_make_usrp_sink( + const uhd::device_addr_t &device_addr, + const uhd::stream_args_t &stream_args +){ return boost::shared_ptr<uhd_usrp_sink>( - new uhd_usrp_sink_impl(device_addr, io_type, num_channels) + new uhd_usrp_sink_impl(device_addr, stream_args) ); } |