UHD: API improvement

master
Xavier Arteaga 5 years ago committed by Xavier Arteaga
parent 405e0c8195
commit 38d9545e99

@ -30,6 +30,7 @@ private:
uhd::usrp::multi_usrp::sptr usrp = nullptr; uhd::usrp::multi_usrp::sptr usrp = nullptr;
const uhd::fs_path TREE_DBOARD_RX_FRONTEND_NAME = "/mboards/0/dboards/A/rx_frontends/A/name"; const uhd::fs_path TREE_DBOARD_RX_FRONTEND_NAME = "/mboards/0/dboards/A/rx_frontends/A/name";
const std::chrono::milliseconds FE_RX_RESET_SLEEP_TIME_MS = std::chrono::milliseconds(2000UL); const std::chrono::milliseconds FE_RX_RESET_SLEEP_TIME_MS = std::chrono::milliseconds(2000UL);
uhd::stream_args_t stream_args;
uhd_error usrp_make_internal(const uhd::device_addr_t& dev_addr) override uhd_error usrp_make_internal(const uhd::device_addr_t& dev_addr) override
{ {
@ -39,14 +40,77 @@ private:
UHD_SAFE_C_SAVE_ERROR(this, usrp = uhd::usrp::multi_usrp::make(dev_addr);) UHD_SAFE_C_SAVE_ERROR(this, usrp = uhd::usrp::multi_usrp::make(dev_addr);)
} }
uhd_error set_tx_subdev(const std::string& string) { UHD_SAFE_C_SAVE_ERROR(this, usrp->set_tx_subdev_spec(string);) }
uhd_error set_rx_subdev(const std::string& string) { UHD_SAFE_C_SAVE_ERROR(this, usrp->set_rx_subdev_spec(string);) }
public: public:
uhd_error usrp_make(const uhd::device_addr_t& dev_addr) override uhd_error usrp_make(const uhd::device_addr_t& dev_addr_, uint32_t nof_channels) override
{ // Make USRP {
uhd::device_addr_t dev_addr = dev_addr_;
// Set transmitter subdevice spec string
std::string tx_subdev;
if (dev_addr.has_key("tx_subdev_spec")) {
tx_subdev = dev_addr.pop("tx_subdev_spec");
}
// Set receiver subdevice spec string
std::string rx_subdev;
if (dev_addr.has_key("rx_subdev_spec")) {
rx_subdev = dev_addr.pop("rx_subdev_spec");
}
// Set over the wire format
std::string otw_format = "sc16";
if (dev_addr.has_key("otw_format")) {
otw_format = dev_addr.pop("otw_format");
}
// Samples-Per-Packet option, 0 means automatic
std::string spp;
if (dev_addr.has_key("spp")) {
spp = dev_addr.pop("spp");
}
// Make USRP
uhd_error err = usrp_multi_make(dev_addr); uhd_error err = usrp_multi_make(dev_addr);
if (err != UHD_ERROR_NONE) { if (err != UHD_ERROR_NONE) {
return err; return err;
} }
// Set transmitter subdev spec if specified
if (not tx_subdev.empty()) {
printf("Setting tx_subdev_spec to '%s'\n", tx_subdev.c_str());
err = set_tx_subdev(tx_subdev);
if (err != UHD_ERROR_NONE) {
return err;
}
}
// Set receiver subdev spec if specified
if (not rx_subdev.empty()) {
printf("Setting rx_subdev_spec to '%s'\n", rx_subdev.c_str());
err = set_rx_subdev(tx_subdev);
if (err != UHD_ERROR_NONE) {
return err;
}
}
// Initialize TX/RX stream args
stream_args.cpu_format = "fc32";
stream_args.otw_format = otw_format;
if (not spp.empty()) {
if (spp == "0") {
Warning(
"The parameter spp is 0, some UHD versions do not handle it as default and receive method will overflow.");
}
stream_args.args.set("spp", spp);
}
stream_args.channels.resize(nof_channels);
for (size_t i = 0; i < (size_t)nof_channels; i++) {
stream_args.channels[i] = i;
}
if (not usrp->get_device()->get_tree()->exists(TREE_DBOARD_RX_FRONTEND_NAME)) { if (not usrp->get_device()->get_tree()->exists(TREE_DBOARD_RX_FRONTEND_NAME)) {
return err; return err;
} }
@ -62,10 +126,8 @@ public:
return err; return err;
} }
uhd::stream_args_t stream_args("fc32", "sc16");
stream_args.channels = {0};
size_t max_samp = 0; size_t max_samp = 0;
err = get_rx_stream(stream_args, max_samp); err = get_rx_stream(max_samp);
// If no error getting RX stream, return // If no error getting RX stream, return
if (err == UHD_ERROR_NONE) { if (err == UHD_ERROR_NONE) {
@ -91,14 +153,6 @@ public:
return err; return err;
} }
uhd_error set_tx_subdev(const std::string& string) override
{
UHD_SAFE_C_SAVE_ERROR(this, usrp->set_tx_subdev_spec(string);)
}
uhd_error set_rx_subdev(const std::string& string) override
{
UHD_SAFE_C_SAVE_ERROR(this, usrp->set_rx_subdev_spec(string);)
}
uhd_error get_mboard_name(std::string& mboard_name) override uhd_error get_mboard_name(std::string& mboard_name) override
{ {
UHD_SAFE_C_SAVE_ERROR(this, mboard_name = usrp->get_mboard_name();) UHD_SAFE_C_SAVE_ERROR(this, mboard_name = usrp->get_mboard_name();)
@ -149,18 +203,18 @@ public:
{ {
UHD_SAFE_C_SAVE_ERROR(this, usrp->set_command_time(timespec);) UHD_SAFE_C_SAVE_ERROR(this, usrp->set_command_time(timespec);)
} }
uhd_error get_rx_stream(const uhd::stream_args_t& args, size_t& max_num_samps) override uhd_error get_rx_stream(size_t& max_num_samps) override
{ {
UHD_SAFE_C_SAVE_ERROR(this, rx_stream = nullptr; rx_stream = usrp->get_rx_stream(args); UHD_SAFE_C_SAVE_ERROR(this, rx_stream = nullptr; rx_stream = usrp->get_rx_stream(stream_args);
max_num_samps = rx_stream->get_max_num_samps(); max_num_samps = rx_stream->get_max_num_samps();
if (max_num_samps == 0UL) { if (max_num_samps == 0UL) {
last_error = "The maximum number of receive samples is zero."; last_error = "The maximum number of receive samples is zero.";
return UHD_ERROR_VALUE; return UHD_ERROR_VALUE;
}) })
} }
uhd_error get_tx_stream(const uhd::stream_args_t& args, size_t& max_num_samps) override uhd_error get_tx_stream(size_t& max_num_samps) override
{ {
UHD_SAFE_C_SAVE_ERROR(this, tx_stream = nullptr; tx_stream = usrp->get_tx_stream(args); UHD_SAFE_C_SAVE_ERROR(this, tx_stream = nullptr; tx_stream = usrp->get_tx_stream(stream_args);
max_num_samps = tx_stream->get_max_num_samps(); max_num_samps = tx_stream->get_max_num_samps();
if (max_num_samps == 0UL) { if (max_num_samps == 0UL) {
last_error = "The maximum number of transmit samples is zero."; last_error = "The maximum number of transmit samples is zero.";

@ -120,7 +120,6 @@ struct rf_uhd_handler_t {
double current_master_clock = 0.0; double current_master_clock = 0.0;
uhd::stream_args_t stream_args;
bool rx_stream_enabled = false; bool rx_stream_enabled = false;
std::mutex tx_mutex; std::mutex tx_mutex;
@ -593,12 +592,6 @@ int rf_uhd_open_multi(char* args, void** h, uint32_t nof_channels)
clock_src = device_addr.pop("clock"); clock_src = device_addr.pop("clock");
} }
// Samples-Per-Packet option, 0 means automatic
std::string spp;
if (device_addr.has_key("spp")) {
spp = device_addr.pop("spp");
}
// Logging level // Logging level
uhd::log::severity_level severity_level = uhd::log::severity_level::info; uhd::log::severity_level severity_level = uhd::log::severity_level::info;
if (device_addr.has_key("log_level")) { if (device_addr.has_key("log_level")) {
@ -630,24 +623,6 @@ int rf_uhd_open_multi(char* args, void** h, uint32_t nof_channels)
} }
#endif #endif
// Set over the wire format
std::string otw_format = "sc16";
if (device_addr.has_key("otw_format")) {
otw_format = device_addr.pop("otw_format");
}
// Set transmitter subdevice spec string
std::string tx_subdev;
if (device_addr.has_key("tx_subdev_spec")) {
tx_subdev = device_addr.pop("tx_subdev_spec");
}
// Set receiver subdevice spec string
std::string rx_subdev;
if (device_addr.has_key("rx_subdev_spec")) {
rx_subdev = device_addr.pop("rx_subdev_spec");
}
// If device type or name not given in args, select device from found list // If device type or name not given in args, select device from found list
if (not device_addr.has_key("type")) { if (not device_addr.has_key("type")) {
// Find available devices // Find available devices
@ -719,29 +694,11 @@ int rf_uhd_open_multi(char* args, void** h, uint32_t nof_channels)
} }
// Make USRP // Make USRP
if (handler->uhd->usrp_make(device_addr) != UHD_ERROR_NONE) { if (handler->uhd->usrp_make(device_addr, nof_channels) != UHD_ERROR_NONE) {
print_usrp_error(handler); print_usrp_error(handler);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
// Set transmitter subdev spec if specified
if (not tx_subdev.empty()) {
printf("Setting tx_subdev_spec to '%s'\n", tx_subdev.c_str());
if (handler->uhd->set_tx_subdev(tx_subdev) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSLTE_ERROR;
}
}
// Set receiver subdev spec if specified
if (not rx_subdev.empty()) {
printf("Setting rx_subdev_spec to '%s'\n", rx_subdev.c_str());
if (handler->uhd->set_rx_subdev(rx_subdev) != UHD_ERROR_NONE) {
print_usrp_error(handler);
return SRSLTE_ERROR;
}
}
// Set device internal name, it sets the device name to B200 by default // Set device internal name, it sets the device name to B200 by default
if (device_addr.has_key("type")) { if (device_addr.has_key("type")) {
if (device_addr["type"] == "x300") { if (device_addr["type"] == "x300") {
@ -806,21 +763,6 @@ int rf_uhd_open_multi(char* args, void** h, uint32_t nof_channels)
} }
} }
// Initialize TX/RX stream args
handler->stream_args.cpu_format = "fc32";
handler->stream_args.otw_format = otw_format;
if (not spp.empty()) {
if (spp == "0") {
Warning(
"The parameter spp is 0, some UHD versions do not handle it as default and receive method will overflow.");
}
handler->stream_args.args.set("spp", spp);
}
handler->stream_args.channels.resize(nof_channels);
for (size_t i = 0; i < (size_t)nof_channels; i++) {
handler->stream_args.channels[i] = i;
}
handler->nof_rx_channels = nof_channels; handler->nof_rx_channels = nof_channels;
handler->nof_tx_channels = nof_channels; handler->nof_tx_channels = nof_channels;
@ -837,12 +779,12 @@ int rf_uhd_open_multi(char* args, void** h, uint32_t nof_channels)
handler->uhd->set_time_unknown_pps(uhd::time_spec_t()); handler->uhd->set_time_unknown_pps(uhd::time_spec_t());
} }
if (handler->uhd->get_rx_stream(handler->stream_args, handler->rx_nof_samples) != UHD_ERROR_NONE) { if (handler->uhd->get_rx_stream(handler->rx_nof_samples) != UHD_ERROR_NONE) {
print_usrp_error(handler); print_usrp_error(handler);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
if (handler->uhd->get_tx_stream(handler->stream_args, handler->tx_nof_samples) != UHD_ERROR_NONE) { if (handler->uhd->get_tx_stream(handler->tx_nof_samples) != UHD_ERROR_NONE) {
print_usrp_error(handler); print_usrp_error(handler);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -973,7 +915,7 @@ double rf_uhd_set_rx_srate(void* h, double freq)
} }
if (RH_UHD_IMP_PROHIBITED_STOP_START.count(handler->devname) == 0) { if (RH_UHD_IMP_PROHIBITED_STOP_START.count(handler->devname) == 0) {
if (handler->uhd->get_rx_stream(handler->stream_args, handler->rx_nof_samples) != UHD_ERROR_NONE) { if (handler->uhd->get_rx_stream(handler->rx_nof_samples) != UHD_ERROR_NONE) {
print_usrp_error(handler); print_usrp_error(handler);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -1027,7 +969,7 @@ double rf_uhd_set_tx_srate(void* h, double freq)
} }
if (RH_UHD_IMP_PROHIBITED_STOP_START.count(handler->devname) == 0) { if (RH_UHD_IMP_PROHIBITED_STOP_START.count(handler->devname) == 0) {
if (handler->uhd->get_tx_stream(handler->stream_args, handler->tx_nof_samples) != UHD_ERROR_NONE) { if (handler->uhd->get_tx_stream(handler->tx_nof_samples) != UHD_ERROR_NONE) {
print_usrp_error(handler); print_usrp_error(handler);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
@ -1243,7 +1185,6 @@ int rf_uhd_recv_with_time_multi(void* h,
print_usrp_error(handler); print_usrp_error(handler);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
rxd_samples = num_rx_samples;
// Save timespec for first block // Save timespec for first block
if (rxd_samples_total == 0) { if (rxd_samples_total == 0) {

@ -313,7 +313,7 @@ public:
return false; return false;
} }
uhd_error usrp_make(const uhd::device_addr_t& _device_addr) override uhd_error usrp_make(const uhd::device_addr_t& _device_addr, uint32_t nof_channels_) override
{ {
// Copy device address // Copy device address
uhd::device_addr_t device_addr = _device_addr; uhd::device_addr_t device_addr = _device_addr;
@ -324,6 +324,18 @@ public:
return err; return err;
} }
// Check number of channels
if (nof_channels_ % nof_channels != 0 or nof_channels_ / nof_channels > nof_radios) {
last_error = "Number of requested channels (" + std::to_string(nof_channels_) +
") is different than the RFNOC "
"available channels (" +
std::to_string(nof_radios * nof_channels) + ")";
return UHD_ERROR_VALUE;
}
// Re-calculate number of radios
nof_radios = nof_channels_ / nof_channels;
// Make USRP // Make USRP
err = usrp_multi_make(device_addr); err = usrp_multi_make(device_addr);
if (err != UHD_ERROR_NONE) { if (err != UHD_ERROR_NONE) {
@ -348,8 +360,6 @@ public:
return UHD_ERROR_NONE; return UHD_ERROR_NONE;
} }
uhd_error set_tx_subdev(const std::string& string) override { return UHD_ERROR_NONE; }
uhd_error set_rx_subdev(const std::string& string) override { return UHD_ERROR_NONE; }
uhd_error get_mboard_name(std::string& mboard_name) override uhd_error get_mboard_name(std::string& mboard_name) override
{ {
mboard_name = "X300"; mboard_name = "X300";
@ -421,7 +431,7 @@ public:
}) })
} }
uhd_error set_command_time(const uhd::time_spec_t& timespec) override { return UHD_ERROR_NONE; } uhd_error set_command_time(const uhd::time_spec_t& timespec) override { return UHD_ERROR_NONE; }
uhd_error get_rx_stream(const uhd::stream_args_t& args, size_t& max_num_samps) override uhd_error get_rx_stream(size_t& max_num_samps) override
{ {
UHD_SAFE_C_SAVE_ERROR( UHD_SAFE_C_SAVE_ERROR(
this, uhd::stream_args_t stream_args("fc32", "sc16"); this, uhd::stream_args_t stream_args("fc32", "sc16");
@ -445,7 +455,7 @@ public:
rx_stream = device3->get_rx_stream(stream_args); rx_stream = device3->get_rx_stream(stream_args);
max_num_samps = rx_stream->get_max_num_samps();) max_num_samps = rx_stream->get_max_num_samps();)
} }
uhd_error get_tx_stream(const uhd::stream_args_t& args, size_t& max_num_samps) override uhd_error get_tx_stream(size_t& max_num_samps) override
{ {
UHD_SAFE_C_SAVE_ERROR( UHD_SAFE_C_SAVE_ERROR(
this, uhd::stream_args_t stream_args("fc32", "sc16"); this, uhd::stream_args_t stream_args("fc32", "sc16");

@ -111,9 +111,7 @@ protected:
public: public:
std::string last_error; std::string last_error;
virtual uhd_error usrp_make(const uhd::device_addr_t& dev_addr) = 0; virtual uhd_error usrp_make(const uhd::device_addr_t& dev_addr, uint32_t nof_channels) = 0;
virtual uhd_error set_tx_subdev(const std::string& string) = 0;
virtual uhd_error set_rx_subdev(const std::string& string) = 0;
virtual uhd_error get_mboard_name(std::string& mboard_name) = 0; virtual uhd_error get_mboard_name(std::string& mboard_name) = 0;
virtual uhd_error get_mboard_sensor_names(std::vector<std::string>& sensors) = 0; virtual uhd_error get_mboard_sensor_names(std::vector<std::string>& sensors) = 0;
virtual uhd_error get_rx_sensor_names(std::vector<std::string>& sensors) = 0; virtual uhd_error get_rx_sensor_names(std::vector<std::string>& sensors) = 0;
@ -147,9 +145,9 @@ public:
virtual uhd_error set_rx_rate(double rate) = 0; virtual uhd_error set_rx_rate(double rate) = 0;
virtual uhd_error set_tx_rate(double rate) = 0; virtual uhd_error set_tx_rate(double rate) = 0;
virtual uhd_error set_command_time(const uhd::time_spec_t& timespec) = 0; virtual uhd_error set_command_time(const uhd::time_spec_t& timespec) = 0;
virtual uhd_error get_rx_stream(const uhd::stream_args_t& args, size_t& max_num_samps) = 0; virtual uhd_error get_rx_stream(size_t& max_num_samps) = 0;
virtual uhd_error destroy_rx_stream() { UHD_SAFE_C_SAVE_ERROR(this, rx_stream = nullptr;) } virtual uhd_error destroy_rx_stream() { UHD_SAFE_C_SAVE_ERROR(this, rx_stream = nullptr;) }
virtual uhd_error get_tx_stream(const uhd::stream_args_t& args, size_t& max_num_samps) = 0; virtual uhd_error get_tx_stream(size_t& max_num_samps) = 0;
virtual uhd_error destroy_tx_stream() { UHD_SAFE_C_SAVE_ERROR(this, rx_stream = nullptr;) } virtual uhd_error destroy_tx_stream() { UHD_SAFE_C_SAVE_ERROR(this, rx_stream = nullptr;) }
virtual uhd_error set_tx_gain(size_t ch, double gain) = 0; virtual uhd_error set_tx_gain(size_t ch, double gain) = 0;
virtual uhd_error set_rx_gain(size_t ch, double gain) = 0; virtual uhd_error set_rx_gain(size_t ch, double gain) = 0;

Loading…
Cancel
Save