2011-06-15 00:25:22 +00:00
|
|
|
//
|
2013-07-15 22:19:58 +00:00
|
|
|
// Copyright 2011-2013 Ettus Research LLC
|
2018-02-19 23:30:32 +00:00
|
|
|
// Copyright 2018 Ettus Research, a National Instruments Company
|
2011-06-15 00:25:22 +00:00
|
|
|
//
|
2018-02-19 23:30:32 +00:00
|
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
2011-06-15 00:25:22 +00:00
|
|
|
//
|
|
|
|
|
|
uhd: Replace all occurrences of boost::bind with std::bind
Note: Replacing everything with a lambda would be even better, but that
can't be easily scripted so we'll do this as a first step to reduce the
Boost footprint.
This also removes occurences of #include <boost/bind.hpp>, and makes
sure all usages of std::bind have an #include <functional>. clang-format
wasn't always applied to minimize the changeset in this commit, however,
it was applied to the blocks of #includes.
Due to conflicts with other Boost libraries, the placeholders _1, _2,
etc. could not be directly used, but had to be explicitly called out
(as std::placeholders::_1, etc.). This makes the use of std::bind even
uglier, which serves as another reminder that using std::bind (and even
more so, boost::bind) should be avoided.
nirio/rpc/rpc_client.cpp still contains a reference to boost::bind. It
was not possible to remove it by simply doing a search and replace, so
it will be removed in a separate commit.
2019-10-16 23:21:19 +00:00
|
|
|
#include "../../transport/super_recv_packet_handler.hpp"
|
|
|
|
|
#include "../../transport/super_send_packet_handler.hpp"
|
2018-01-31 19:20:14 +00:00
|
|
|
#include "b100_impl.hpp"
|
|
|
|
|
#include <uhd/utils/log.hpp>
|
|
|
|
|
#include <uhdlib/usrp/common/validate_subdev_spec.hpp>
|
2011-06-15 00:25:22 +00:00
|
|
|
#include <boost/format.hpp>
|
|
|
|
|
#include <boost/thread.hpp>
|
uhd: Replace all occurrences of boost::bind with std::bind
Note: Replacing everything with a lambda would be even better, but that
can't be easily scripted so we'll do this as a first step to reduce the
Boost footprint.
This also removes occurences of #include <boost/bind.hpp>, and makes
sure all usages of std::bind have an #include <functional>. clang-format
wasn't always applied to minimize the changeset in this commit, however,
it was applied to the blocks of #includes.
Due to conflicts with other Boost libraries, the placeholders _1, _2,
etc. could not be directly used, but had to be explicitly called out
(as std::placeholders::_1, etc.). This makes the use of std::bind even
uglier, which serves as another reminder that using std::bind (and even
more so, boost::bind) should be avoided.
nirio/rpc/rpc_client.cpp still contains a reference to boost::bind. It
was not possible to remove it by simply doing a search and replace, so
it will be removed in a separate commit.
2019-10-16 23:21:19 +00:00
|
|
|
#include <functional>
|
2019-09-28 09:18:57 +00:00
|
|
|
#include <memory>
|
2011-06-15 00:25:22 +00:00
|
|
|
|
|
|
|
|
using namespace uhd;
|
|
|
|
|
using namespace uhd::usrp;
|
|
|
|
|
using namespace uhd::transport;
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
void b100_impl::update_rates(void)
|
|
|
|
|
{
|
2011-10-11 21:54:02 +00:00
|
|
|
const fs_path mb_path = "/mboards/0";
|
|
|
|
|
_tree->access<double>(mb_path / "tick_rate").update();
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// and now that the tick rate is set, init the host rates to something
|
|
|
|
|
for (const std::string& name : _tree->list(mb_path / "rx_dsps")) {
|
2011-10-11 21:54:02 +00:00
|
|
|
_tree->access<double>(mb_path / "rx_dsps" / name / "rate" / "value").update();
|
|
|
|
|
}
|
2020-03-02 23:25:13 +00:00
|
|
|
for (const std::string& name : _tree->list(mb_path / "tx_dsps")) {
|
2011-10-11 21:54:02 +00:00
|
|
|
_tree->access<double>(mb_path / "tx_dsps" / name / "rate" / "value").update();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
void b100_impl::update_tick_rate(const double rate)
|
|
|
|
|
{
|
|
|
|
|
// update the tick rate on all existing streamers -> thread safe
|
|
|
|
|
for (size_t i = 0; i < _rx_streamers.size(); i++) {
|
2019-09-28 09:18:57 +00:00
|
|
|
std::shared_ptr<sph::recv_packet_streamer> my_streamer =
|
|
|
|
|
std::dynamic_pointer_cast<sph::recv_packet_streamer>(_rx_streamers[i].lock());
|
2020-03-02 23:25:13 +00:00
|
|
|
if (my_streamer.get() == NULL)
|
|
|
|
|
continue;
|
2011-10-11 21:54:02 +00:00
|
|
|
my_streamer->set_tick_rate(rate);
|
|
|
|
|
}
|
2020-03-02 23:25:13 +00:00
|
|
|
for (size_t i = 0; i < _tx_streamers.size(); i++) {
|
2019-09-28 09:18:57 +00:00
|
|
|
std::shared_ptr<sph::send_packet_streamer> my_streamer =
|
|
|
|
|
std::dynamic_pointer_cast<sph::send_packet_streamer>(_tx_streamers[i].lock());
|
2020-03-02 23:25:13 +00:00
|
|
|
if (my_streamer.get() == NULL)
|
|
|
|
|
continue;
|
2011-10-11 21:54:02 +00:00
|
|
|
my_streamer->set_tick_rate(rate);
|
|
|
|
|
}
|
2011-06-30 04:16:28 +00:00
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
void b100_impl::update_rx_samp_rate(const size_t dspno, const double rate)
|
|
|
|
|
{
|
2019-09-28 09:18:57 +00:00
|
|
|
std::shared_ptr<sph::recv_packet_streamer> my_streamer =
|
|
|
|
|
std::dynamic_pointer_cast<sph::recv_packet_streamer>(_rx_streamers[dspno].lock());
|
2020-03-02 23:25:13 +00:00
|
|
|
if (my_streamer.get() == NULL)
|
|
|
|
|
return;
|
2011-10-11 21:54:02 +00:00
|
|
|
|
|
|
|
|
my_streamer->set_samp_rate(rate);
|
|
|
|
|
const double adj = _rx_dsps[dspno]->get_scaling_adjustment();
|
|
|
|
|
my_streamer->set_scale_factor(adj);
|
2011-06-30 04:16:28 +00:00
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
void b100_impl::update_tx_samp_rate(const size_t dspno, const double rate)
|
|
|
|
|
{
|
2019-09-28 09:18:57 +00:00
|
|
|
std::shared_ptr<sph::send_packet_streamer> my_streamer =
|
|
|
|
|
std::dynamic_pointer_cast<sph::send_packet_streamer>(_tx_streamers[dspno].lock());
|
2020-03-02 23:25:13 +00:00
|
|
|
if (my_streamer.get() == NULL)
|
|
|
|
|
return;
|
2011-10-11 21:54:02 +00:00
|
|
|
|
|
|
|
|
my_streamer->set_samp_rate(rate);
|
2012-01-29 00:08:17 +00:00
|
|
|
const double adj = _tx_dsp->get_scaling_adjustment();
|
|
|
|
|
my_streamer->set_scale_factor(adj);
|
2011-06-30 04:16:28 +00:00
|
|
|
}
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
void b100_impl::update_rx_subdev_spec(const uhd::usrp::subdev_spec_t& spec)
|
|
|
|
|
{
|
2011-07-22 08:19:03 +00:00
|
|
|
fs_path root = "/mboards/0/dboards";
|
2011-06-30 04:16:28 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// sanity checking
|
2011-07-01 22:07:38 +00:00
|
|
|
validate_subdev_spec(_tree, spec, "rx");
|
2011-06-30 04:16:28 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// setup mux for this spec
|
2011-07-04 14:21:53 +00:00
|
|
|
bool fe_swapped = false;
|
2020-03-02 23:25:13 +00:00
|
|
|
for (size_t i = 0; i < spec.size(); i++) {
|
|
|
|
|
const std::string conn =
|
|
|
|
|
_tree
|
|
|
|
|
->access<std::string>(root / spec[i].db_name / "rx_frontends"
|
|
|
|
|
/ spec[i].sd_name / "connection")
|
|
|
|
|
.get();
|
|
|
|
|
if (i == 0 and (conn == "QI" or conn == "Q"))
|
|
|
|
|
fe_swapped = true;
|
2011-07-04 14:21:53 +00:00
|
|
|
_rx_dsps[i]->set_mux(conn, fe_swapped);
|
2011-06-30 04:16:28 +00:00
|
|
|
}
|
2011-07-04 14:21:53 +00:00
|
|
|
_rx_fe->set_mux(fe_swapped);
|
2011-06-30 04:16:28 +00:00
|
|
|
}
|
2011-06-15 00:25:22 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
void b100_impl::update_tx_subdev_spec(const uhd::usrp::subdev_spec_t& spec)
|
|
|
|
|
{
|
2011-07-22 08:19:03 +00:00
|
|
|
fs_path root = "/mboards/0/dboards";
|
2011-06-30 04:16:28 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// sanity checking
|
2011-07-01 22:07:38 +00:00
|
|
|
validate_subdev_spec(_tree, spec, "tx");
|
2011-06-30 04:16:28 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// set the mux for this spec
|
|
|
|
|
const std::string conn =
|
|
|
|
|
_tree
|
|
|
|
|
->access<std::string>(
|
|
|
|
|
root / spec[0].db_name / "tx_frontends" / spec[0].sd_name / "connection")
|
|
|
|
|
.get();
|
2011-06-30 04:16:28 +00:00
|
|
|
_tx_fe->set_mux(conn);
|
2011-06-15 00:25:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***********************************************************************
|
2011-06-30 04:16:28 +00:00
|
|
|
* Async Data
|
|
|
|
|
**********************************************************************/
|
2020-03-02 23:25:13 +00:00
|
|
|
bool b100_impl::recv_async_msg(async_metadata_t& async_metadata, double timeout)
|
|
|
|
|
{
|
2012-07-02 20:59:05 +00:00
|
|
|
return _fifo_ctrl->pop_async_msg(async_metadata, timeout);
|
2011-06-30 04:16:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***********************************************************************
|
2011-10-11 21:54:02 +00:00
|
|
|
* Receive streamer
|
2011-06-15 00:25:22 +00:00
|
|
|
**********************************************************************/
|
2020-03-02 23:25:13 +00:00
|
|
|
rx_streamer::sptr b100_impl::get_rx_stream(const uhd::stream_args_t& args_)
|
|
|
|
|
{
|
2011-10-11 21:54:02 +00:00
|
|
|
stream_args_t args = args_;
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// setup defaults for unspecified values
|
|
|
|
|
args.otw_format = args.otw_format.empty() ? "sc16" : args.otw_format;
|
|
|
|
|
args.channels = args.channels.empty() ? std::vector<size_t>(1, 0) : args.channels;
|
|
|
|
|
|
|
|
|
|
// calculate packet size
|
|
|
|
|
static const size_t hdr_size =
|
|
|
|
|
0 + vrt::max_if_hdr_words32 * sizeof(uint32_t)
|
|
|
|
|
+ sizeof(vrt::if_packet_info_t().tlr) // forced to have trailer
|
|
|
|
|
- sizeof(vrt::if_packet_info_t().cid) // no class id ever used
|
|
|
|
|
- sizeof(vrt::if_packet_info_t().tsi) // no int time ever used
|
|
|
|
|
;
|
2012-02-15 00:34:36 +00:00
|
|
|
const size_t bpp = _data_transport->get_recv_frame_size() - hdr_size;
|
2012-01-17 07:04:53 +00:00
|
|
|
const size_t bpi = convert::get_bytes_per_item(args.otw_format);
|
2020-03-02 23:25:13 +00:00
|
|
|
const size_t spp = unsigned(args.args.cast<double>("spp", bpp / bpi));
|
2011-10-11 21:54:02 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// make the new streamer given the samples per packet
|
|
|
|
|
std::shared_ptr<sph::recv_packet_streamer> my_streamer =
|
|
|
|
|
std::make_shared<sph::recv_packet_streamer>(spp);
|
2011-10-11 21:54:02 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// init some streamer stuff
|
2011-10-11 21:54:02 +00:00
|
|
|
my_streamer->resize(args.channels.size());
|
|
|
|
|
my_streamer->set_vrt_unpacker(&vrt::if_hdr_unpack_le);
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// set the converter
|
2011-10-11 21:54:02 +00:00
|
|
|
uhd::convert::id_type id;
|
2020-03-02 23:25:13 +00:00
|
|
|
id.input_format = args.otw_format + "_item32_le";
|
|
|
|
|
id.num_inputs = 1;
|
2011-10-12 07:39:04 +00:00
|
|
|
id.output_format = args.cpu_format;
|
2020-03-02 23:25:13 +00:00
|
|
|
id.num_outputs = 1;
|
2011-10-11 21:54:02 +00:00
|
|
|
my_streamer->set_converter(id);
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// bind callbacks for the handler
|
|
|
|
|
for (size_t chan_i = 0; chan_i < args.channels.size(); chan_i++) {
|
2011-10-11 21:54:02 +00:00
|
|
|
const size_t dsp = args.channels[chan_i];
|
2020-03-02 23:25:13 +00:00
|
|
|
_rx_dsps[dsp]->set_nsamps_per_packet(spp); // seems to be a good place to set this
|
2012-01-29 00:08:17 +00:00
|
|
|
_rx_dsps[dsp]->setup(args);
|
2013-07-19 21:03:30 +00:00
|
|
|
_recv_demuxer->realloc_sid(B100_RX_SID_BASE + dsp);
|
2020-03-02 23:25:13 +00:00
|
|
|
my_streamer->set_xport_chan_get_buff(chan_i,
|
|
|
|
|
std::bind(&recv_packet_demuxer_3000::get_recv_buff,
|
|
|
|
|
_recv_demuxer,
|
|
|
|
|
B100_RX_SID_BASE + dsp,
|
|
|
|
|
std::placeholders::_1),
|
|
|
|
|
true /*flush*/);
|
|
|
|
|
my_streamer->set_overflow_handler(
|
|
|
|
|
chan_i, std::bind(&rx_dsp_core_200::handle_overflow, _rx_dsps[dsp]));
|
|
|
|
|
my_streamer->set_issue_stream_cmd(chan_i,
|
|
|
|
|
std::bind(&rx_dsp_core_200::issue_stream_command,
|
|
|
|
|
_rx_dsps[dsp],
|
|
|
|
|
std::placeholders::_1));
|
|
|
|
|
_rx_streamers[dsp] = my_streamer; // store weak pointer
|
2011-10-11 21:54:02 +00:00
|
|
|
}
|
2011-06-15 00:25:22 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// sets all tick and samp rates on this streamer
|
2011-10-11 21:54:02 +00:00
|
|
|
this->update_rates();
|
|
|
|
|
|
|
|
|
|
return my_streamer;
|
2011-06-15 00:25:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***********************************************************************
|
2011-10-11 21:54:02 +00:00
|
|
|
* Transmit streamer
|
2011-06-15 00:25:22 +00:00
|
|
|
**********************************************************************/
|
2020-03-02 23:25:13 +00:00
|
|
|
tx_streamer::sptr b100_impl::get_tx_stream(const uhd::stream_args_t& args_)
|
|
|
|
|
{
|
2011-10-11 21:54:02 +00:00
|
|
|
stream_args_t args = args_;
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// setup defaults for unspecified values
|
|
|
|
|
args.otw_format = args.otw_format.empty() ? "sc16" : args.otw_format;
|
|
|
|
|
args.channels = args.channels.empty() ? std::vector<size_t>(1, 0) : args.channels;
|
|
|
|
|
|
|
|
|
|
// calculate packet size
|
|
|
|
|
static const size_t hdr_size =
|
|
|
|
|
0 + vrt::max_if_hdr_words32 * sizeof(uint32_t)
|
|
|
|
|
+ sizeof(vrt::if_packet_info_t().tlr) // forced to have trailer
|
|
|
|
|
- sizeof(vrt::if_packet_info_t().sid) // no stream id ever used
|
|
|
|
|
- sizeof(vrt::if_packet_info_t().cid) // no class id ever used
|
|
|
|
|
- sizeof(vrt::if_packet_info_t().tsi) // no int time ever used
|
|
|
|
|
;
|
2012-02-15 00:34:36 +00:00
|
|
|
static const size_t bpp = _data_transport->get_send_frame_size() - hdr_size;
|
2020-03-02 23:25:13 +00:00
|
|
|
const size_t spp = bpp / convert::get_bytes_per_item(args.otw_format);
|
2011-10-11 21:54:02 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// make the new streamer given the samples per packet
|
|
|
|
|
std::shared_ptr<sph::send_packet_streamer> my_streamer =
|
|
|
|
|
std::make_shared<sph::send_packet_streamer>(spp);
|
2011-10-11 21:54:02 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// init some streamer stuff
|
2011-10-11 21:54:02 +00:00
|
|
|
my_streamer->resize(args.channels.size());
|
|
|
|
|
my_streamer->set_vrt_packer(&vrt::if_hdr_pack_le);
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// set the converter
|
2011-10-11 21:54:02 +00:00
|
|
|
uhd::convert::id_type id;
|
2020-03-02 23:25:13 +00:00
|
|
|
id.input_format = args.cpu_format;
|
|
|
|
|
id.num_inputs = 1;
|
2011-10-12 07:39:04 +00:00
|
|
|
id.output_format = args.otw_format + "_item32_le";
|
2020-03-02 23:25:13 +00:00
|
|
|
id.num_outputs = 1;
|
2011-10-11 21:54:02 +00:00
|
|
|
my_streamer->set_converter(id);
|
|
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// bind callbacks for the handler
|
|
|
|
|
for (size_t chan_i = 0; chan_i < args.channels.size(); chan_i++) {
|
2011-10-11 21:54:02 +00:00
|
|
|
const size_t dsp = args.channels[chan_i];
|
2020-03-02 23:25:13 +00:00
|
|
|
UHD_ASSERT_THROW(dsp == 0); // always 0
|
2012-01-29 00:08:17 +00:00
|
|
|
_tx_dsp->setup(args);
|
2020-03-02 23:25:13 +00:00
|
|
|
my_streamer->set_xport_chan_get_buff(chan_i,
|
|
|
|
|
std::bind(
|
|
|
|
|
&zero_copy_if::get_send_buff, _data_transport, std::placeholders::_1));
|
|
|
|
|
my_streamer->set_async_receiver(std::bind(&fifo_ctrl_excelsior::pop_async_msg,
|
|
|
|
|
_fifo_ctrl,
|
|
|
|
|
std::placeholders::_1,
|
|
|
|
|
std::placeholders::_2));
|
|
|
|
|
_tx_streamers[dsp] = my_streamer; // store weak pointer
|
2011-10-11 21:54:02 +00:00
|
|
|
}
|
2011-06-15 00:25:22 +00:00
|
|
|
|
2020-03-02 23:25:13 +00:00
|
|
|
// sets all tick and samp rates on this streamer
|
2011-10-11 21:54:02 +00:00
|
|
|
this->update_rates();
|
|
|
|
|
|
|
|
|
|
return my_streamer;
|
2011-06-15 00:25:22 +00:00
|
|
|
}
|