summaryrefslogtreecommitdiff
path: root/gr-uhd/lib/gr_uhd_usrp_sink.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gr-uhd/lib/gr_uhd_usrp_sink.cc')
-rw-r--r--gr-uhd/lib/gr_uhd_usrp_sink.cc169
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)
);
}