|
|
@ -64,9 +64,11 @@ private:
|
|
|
|
#endif // UHD_ENABLE_CUSTOM_RFNOC
|
|
|
|
#endif // UHD_ENABLE_CUSTOM_RFNOC
|
|
|
|
|
|
|
|
|
|
|
|
const std::string DMA_FIFO_BLOCK_NAME = "DmaFIFO";
|
|
|
|
const std::string DMA_FIFO_BLOCK_NAME = "DmaFIFO";
|
|
|
|
|
|
|
|
const std::string FIFO_BLOCK_NAME = "FIFO";
|
|
|
|
const std::chrono::milliseconds SETUP_TIME_MS = std::chrono::milliseconds(1000UL);
|
|
|
|
const std::chrono::milliseconds SETUP_TIME_MS = std::chrono::milliseconds(1000UL);
|
|
|
|
const uhd::fs_path TREE_MBOARD_SENSORS = "/mboards/0/sensors";
|
|
|
|
const uhd::fs_path TREE_MBOARD_SENSORS = "/mboards/0/sensors";
|
|
|
|
const uhd::fs_path TREE_RX_SENSORS = "/mboards/0/dboards/A/rx_frontends/0/sensors";
|
|
|
|
const uhd::fs_path TREE_RX_SENSORS = "/mboards/0/dboards/A/rx_frontends/0/sensors";
|
|
|
|
|
|
|
|
const uhd::fs_path TREE_TIME_NOW = "/mboards/0/time/now";
|
|
|
|
const std::string TX_ANTENNA_PORT = "TX/RX";
|
|
|
|
const std::string TX_ANTENNA_PORT = "TX/RX";
|
|
|
|
const std::string RX_ANTENNA_PORT = "RX2";
|
|
|
|
const std::string RX_ANTENNA_PORT = "RX2";
|
|
|
|
const size_t spp = 1920 / 8;
|
|
|
|
const size_t spp = 1920 / 8;
|
|
|
@ -96,8 +98,9 @@ private:
|
|
|
|
std::vector<uhd::rfnoc::block_id_t> duc_id = {};
|
|
|
|
std::vector<uhd::rfnoc::block_id_t> duc_id = {};
|
|
|
|
|
|
|
|
|
|
|
|
// DMA FIFO Control
|
|
|
|
// DMA FIFO Control
|
|
|
|
uhd::rfnoc::dma_fifo_block_ctrl::sptr dma_ctrl = {};
|
|
|
|
bool use_dma = false;
|
|
|
|
uhd::rfnoc::block_id_t dma_id = {};
|
|
|
|
std::vector<uhd::rfnoc::block_ctrl_base::sptr> fifo_ctrl = {};
|
|
|
|
|
|
|
|
std::vector<uhd::rfnoc::block_id_t> fifo_id = {};
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -275,19 +278,39 @@ private:
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check whether using DMA or FIFO
|
|
|
|
|
|
|
|
use_dma = device3->find_blocks(FIFO_BLOCK_NAME).size() < (nof_radios * nof_channels);
|
|
|
|
|
|
|
|
|
|
|
|
// Create DMA FIFO control
|
|
|
|
// Create DMA FIFO control
|
|
|
|
dma_id = uhd::rfnoc::block_id_t(0, DMA_FIFO_BLOCK_NAME);
|
|
|
|
if (use_dma) {
|
|
|
|
dma_ctrl = device3->get_block_ctrl<uhd::rfnoc::dma_fifo_block_ctrl>(dma_id);
|
|
|
|
// One FIFO for all channels
|
|
|
|
|
|
|
|
fifo_id.resize(1);
|
|
|
|
|
|
|
|
fifo_ctrl.resize(1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Get block
|
|
|
|
|
|
|
|
fifo_id[0] = uhd::rfnoc::block_id_t(0, DMA_FIFO_BLOCK_NAME);
|
|
|
|
|
|
|
|
fifo_ctrl[0] = device3->get_block_ctrl<uhd::rfnoc::block_ctrl_base>(fifo_id[0]);
|
|
|
|
|
|
|
|
|
|
|
|
// Configure DMA Channels
|
|
|
|
// Configure DMA Channels
|
|
|
|
for (size_t i = 0; i < nof_radios * nof_channels; i++) {
|
|
|
|
for (size_t i = 0; i < nof_radios * nof_channels; i++) {
|
|
|
|
uhd::device_addr_t dma_fifo_args;
|
|
|
|
uhd::device_addr_t dma_fifo_args;
|
|
|
|
dma_fifo_args.set("base_addr", std::to_string(dma_fifo_depth * i));
|
|
|
|
dma_fifo_args.set("base_addr", std::to_string(dma_fifo_depth * i));
|
|
|
|
dma_fifo_args.set("depth", std::to_string(dma_fifo_depth));
|
|
|
|
dma_fifo_args.set("depth", std::to_string(dma_fifo_depth));
|
|
|
|
|
|
|
|
|
|
|
|
UHD_LOG_DEBUG(dma_id, "Setting channel " << i << " args: " << dma_fifo_args.to_string());
|
|
|
|
UHD_LOG_DEBUG(fifo_id[0], "Setting channel " << i << " args: " << dma_fifo_args.to_string());
|
|
|
|
|
|
|
|
|
|
|
|
dma_ctrl->set_args(dma_fifo_args, i);
|
|
|
|
fifo_ctrl[0]->set_args(dma_fifo_args, i);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// One FIFO for every channel
|
|
|
|
|
|
|
|
fifo_id.resize(nof_radios * nof_channels);
|
|
|
|
|
|
|
|
fifo_ctrl.resize(nof_radios * nof_channels);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < nof_radios * nof_channels; i++) {
|
|
|
|
|
|
|
|
// Get block
|
|
|
|
|
|
|
|
fifo_id[i] = uhd::rfnoc::block_id_t(0, FIFO_BLOCK_NAME, i);
|
|
|
|
|
|
|
|
fifo_ctrl[i] = device3->get_block_ctrl<uhd::rfnoc::block_ctrl_base>(fifo_id[i]);
|
|
|
|
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -299,29 +322,38 @@ private:
|
|
|
|
nof_samples_per_packet = spp * 4 + 2 * sizeof(uint64_t);
|
|
|
|
nof_samples_per_packet = spp * 4 + 2 * sizeof(uint64_t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UHD_SAFE_C_SAVE_ERROR(this,
|
|
|
|
UHD_SAFE_C_SAVE_ERROR(
|
|
|
|
|
|
|
|
this,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Get Tx and Rx Graph
|
|
|
|
|
|
|
|
graph = device3->create_graph("graph");
|
|
|
|
|
|
|
|
|
|
|
|
// Get Tx and Rx Graph
|
|
|
|
for (size_t i = 0; i < nof_radios; i++) {
|
|
|
|
graph = device3->create_graph("graph");
|
|
|
|
// Radio -> DDC
|
|
|
|
|
|
|
|
UHD_LOG_DEBUG(graph->get_name(), "Connecting " << radio_id[i] << " -> " << ddc_id[i]);
|
|
|
|
for (size_t i = 0; i < nof_radios; i++) {
|
|
|
|
graph->connect(radio_id[i], 0, ddc_id[i], 0, nof_samples_per_packet);
|
|
|
|
// Radio -> DDC
|
|
|
|
|
|
|
|
UHD_LOG_DEBUG(graph->get_name(), "Connecting " << radio_id[i] << " -> " << ddc_id[i]);
|
|
|
|
// DUC -> Radio
|
|
|
|
graph->connect(radio_id[i], 0, ddc_id[i], 0, nof_samples_per_packet);
|
|
|
|
UHD_LOG_DEBUG(graph->get_name(), "Connecting " << duc_id[i] << " -> " << radio_id[i]);
|
|
|
|
|
|
|
|
graph->connect(duc_id[i], 0, radio_id[i], 0, nof_samples_per_packet);
|
|
|
|
// DUC -> Radio
|
|
|
|
|
|
|
|
UHD_LOG_DEBUG(graph->get_name(), "Connecting " << duc_id[i] << " -> " << radio_id[i]);
|
|
|
|
if (use_dma) {
|
|
|
|
graph->connect(duc_id[i], 0, radio_id[i], 0, nof_samples_per_packet);
|
|
|
|
// DMA FIFO -> DUC
|
|
|
|
|
|
|
|
for (size_t j = 0; j < nof_channels; j++) {
|
|
|
|
// DMA FIFO -> DUC
|
|
|
|
size_t dma_port = i * nof_channels + j;
|
|
|
|
for (size_t j = 0; j < nof_channels; j++) {
|
|
|
|
UHD_LOG_DEBUG(graph->get_name(),
|
|
|
|
size_t dma_port = i * nof_channels + j;
|
|
|
|
"Connecting " << fifo_id[0] << ":" << dma_port << " -> " << duc_id[i] << ":" << j);
|
|
|
|
UHD_LOG_DEBUG(graph->get_name(),
|
|
|
|
graph->connect(fifo_id[0], dma_port, duc_id[i], j, nof_samples_per_packet);
|
|
|
|
"Connecting " << dma_id << ":" << dma_port << " -> " << duc_id[i] << ":"
|
|
|
|
}
|
|
|
|
<< j);
|
|
|
|
} else {
|
|
|
|
graph->connect(dma_id, dma_port, duc_id[i], j, nof_samples_per_packet);
|
|
|
|
// FIFO -> DUC
|
|
|
|
}
|
|
|
|
for (size_t j = 0; j < nof_channels; j++) {
|
|
|
|
})
|
|
|
|
size_t fifo_idx = i * nof_channels + j;
|
|
|
|
|
|
|
|
UHD_LOG_DEBUG(graph->get_name(), "Connecting " << fifo_id[fifo_idx] << ":0 -> " << duc_id[i] << ":" << j);
|
|
|
|
|
|
|
|
graph->connect(fifo_id[fifo_idx], 0, duc_id[i], j, nof_samples_per_packet);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uhd_error connect_loopback()
|
|
|
|
uhd_error connect_loopback()
|
|
|
@ -332,25 +364,34 @@ private:
|
|
|
|
nof_samples_per_packet = spp * 4 + 2 * sizeof(uint64_t);
|
|
|
|
nof_samples_per_packet = spp * 4 + 2 * sizeof(uint64_t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UHD_SAFE_C_SAVE_ERROR(this,
|
|
|
|
UHD_SAFE_C_SAVE_ERROR(
|
|
|
|
|
|
|
|
this,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Get Tx and Rx Graph
|
|
|
|
|
|
|
|
graph = device3->create_graph("graph");
|
|
|
|
|
|
|
|
|
|
|
|
// Get Tx and Rx Graph
|
|
|
|
for (size_t i = 0; i < nof_radios; i++) {
|
|
|
|
graph = device3->create_graph("graph");
|
|
|
|
// DUC -> DDC
|
|
|
|
|
|
|
|
UHD_LOG_DEBUG(graph->get_name(), "Connecting " << duc_id[i] << " -> " << ddc_id[i]);
|
|
|
|
for (size_t i = 0; i < nof_radios; i++) {
|
|
|
|
graph->connect(duc_id[i], 0, ddc_id[i], 0, nof_samples_per_packet);
|
|
|
|
// DUC -> DDC
|
|
|
|
|
|
|
|
UHD_LOG_DEBUG(graph->get_name(), "Connecting " << duc_id[i] << " -> " << ddc_id[i]);
|
|
|
|
if (use_dma) {
|
|
|
|
graph->connect(duc_id[i], 0, ddc_id[i], 0, nof_samples_per_packet);
|
|
|
|
for (size_t j = 0; j < nof_channels; j++) {
|
|
|
|
|
|
|
|
// DMA FIFO -> DUC
|
|
|
|
for (size_t j = 0; j < nof_channels; j++) {
|
|
|
|
size_t dma_port = i * nof_channels + j;
|
|
|
|
// DMA FIFO -> DUC
|
|
|
|
UHD_LOG_DEBUG(graph->get_name(),
|
|
|
|
size_t dma_port = i * nof_channels + j;
|
|
|
|
"Connecting " << fifo_id[0] << ":" << dma_port << " -> " << duc_id[i] << ":" << j);
|
|
|
|
UHD_LOG_DEBUG(graph->get_name(),
|
|
|
|
graph->connect(fifo_id[0], dma_port, duc_id[i], j, nof_samples_per_packet);
|
|
|
|
"Connecting " << dma_id << ":" << dma_port << " -> " << duc_id[i] << ":"
|
|
|
|
}
|
|
|
|
<< j);
|
|
|
|
} else {
|
|
|
|
graph->connect(dma_id, dma_port, duc_id[i], j, nof_samples_per_packet);
|
|
|
|
for (size_t j = 0; j < nof_channels; j++) {
|
|
|
|
}
|
|
|
|
// DMA FIFO -> DUC
|
|
|
|
})
|
|
|
|
size_t fifo_idx = i * nof_channels + j;
|
|
|
|
|
|
|
|
UHD_LOG_DEBUG(graph->get_name(), "Connecting " << fifo_id[fifo_idx] << ":0 -> " << duc_id[i] << ":" << j);
|
|
|
|
|
|
|
|
graph->connect(fifo_id[fifo_idx], 0, duc_id[i], j, nof_samples_per_packet);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
public:
|
|
|
@ -452,12 +493,8 @@ public:
|
|
|
|
}
|
|
|
|
}
|
|
|
|
uhd_error get_time_now(uhd::time_spec_t& timespec) override
|
|
|
|
uhd_error get_time_now(uhd::time_spec_t& timespec) override
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (loopback) {
|
|
|
|
UHD_SAFE_C_SAVE_ERROR(this, timespec = device3->get_tree()->access<uhd::time_spec_t>(TREE_TIME_NOW).get();
|
|
|
|
timespec = 0.0;
|
|
|
|
Info("-- " << timespec.get_real_secs());)
|
|
|
|
return UHD_ERROR_NONE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
UHD_SAFE_C_SAVE_ERROR(this, timespec = radio_ctrl[0]->get_time_now(););
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
uhd_error set_sync_source(const std::string& source) override
|
|
|
|
uhd_error set_sync_source(const std::string& source) override
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -536,10 +573,15 @@ public:
|
|
|
|
for (size_t i = 0; i < nof_radios; i++) {
|
|
|
|
for (size_t i = 0; i < nof_radios; i++) {
|
|
|
|
for (size_t j = 0; j < nof_channels; j++, channel_count++) {
|
|
|
|
for (size_t j = 0; j < nof_channels; j++, channel_count++) {
|
|
|
|
std::string channel_str = std::to_string(channel_count);
|
|
|
|
std::string channel_str = std::to_string(channel_count);
|
|
|
|
|
|
|
|
if (use_dma) {
|
|
|
|
stream_args.args["block_id" + channel_str] = dma_id;
|
|
|
|
stream_args.args["block_id" + channel_str] = fifo_id[0];
|
|
|
|
stream_args.args["block_port" + channel_str] = channel_str;
|
|
|
|
stream_args.args["block_port" + channel_str] = channel_str;
|
|
|
|
stream_args.channels[channel_count] = channel_count;
|
|
|
|
stream_args.channels[channel_count] = channel_count;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
stream_args.args["block_id" + channel_str] = fifo_id[channel_count];
|
|
|
|
|
|
|
|
stream_args.args["block_port" + channel_str] = "0";
|
|
|
|
|
|
|
|
stream_args.channels[channel_count] = channel_count;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|