Hey Guys, I'm working on a RFNoC/UHD application, where I'd ideally like to run with one FFT size, and then later change to another size.
But I seem to be doing something wrong here, because I can run fine with my initial configuration. But if I make a change to the block arguments, I get a timeout error when I issue a recv command using NUM_SAMPS_AND_DONE. Code attached, showing what I'm seeing but here's a sketch of what I'm trying to do when I reconfigure my blocks: //----------snip----------- usrp->clear(); //reduce FFT size fft_size=256; fft_block_ctrl->set_args(uhd::device_addr_t("spp=" + std::to_string(fft_size) + ",direction=forward,shift=normal,magnitude_out=COMPLEX")); //--------snip-------------- Any ideas on how to properly reconfigure block parameters? For reference I'm using: E310-sg3 GCC 7.3.0 UHD rfnoc-devl branch (commit 1f8463cc) Thanks, Christian Valledor
/****************************************************************************** * * RFNoC Graph Change test * * C. Valledor * 2018-12-06 * *****************************************************************************/ #include <uhd/types/tune_request.hpp> #include <uhd/types/sensors.hpp> #include <uhd/utils/thread_priority.hpp> #include <uhd/utils/safe_main.hpp> #include <uhd/device3.hpp> #include <uhd/rfnoc/radio_ctrl.hpp> #include <uhd/rfnoc/source_block_ctrl_base.hpp> #include <uhd/exception.hpp> #include <boost/program_options.hpp> #include <boost/format.hpp> #include <boost/thread.hpp> #include <vector> #include <iostream> #include <fstream> #include <csignal> #include <complex> #include <ctime> #include <chrono> #include <algorithm> #include <numeric> namespace po = boost::program_options; static bool stop_signal_called = false; void sig_int_handler(int){stop_signal_called = true;} int UHD_SAFE_MAIN(int argc, char *argv[]){ uhd::set_thread_priority_safe(); /************************************************************************ * Argument Handling ***********************************************************************/ //variables to be set by po double rate = 5.12e6; double freq = 900e6; double bw = 5.16e6; double setup_time=1; size_t radio_id=0; size_t radio_chan=0; size_t spp=512; double master_clock_rate=50e6; double gain=15; size_t fft_size=512; std::string ant="RX2"; //setup the program options po::options_description desc("Allowed options"); desc.add_options() ("help", "help message") ("freq", po::value<double>(&freq)->default_value(900e6), "RF frequency in Hz") ("gain", po::value<double>(&gain)->default_value(15), "RX gain value in dB") ("timing", "debug flag to show frame timing") ; po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); //print the help message if (vm.count("help")) { std::cout << boost::format("UHD/RFNoC graph update %s") % desc << std::endl; return ~0; } // Set values not taken from command line std::string format = "sc16"; bool debug_flag = vm.count("debug") > 0; bool time_flag = vm.count("timing") > 0; /************************************************************************ * Device Setup ***********************************************************************/ // make the USRP uhd::device3::sptr usrp = uhd::device3::make((std::string) "type=e3x0"); std::cout << "USRP build" << std::endl; // Get Radio Control uhd::rfnoc::block_id_t radio_ctrl_id = uhd::rfnoc::block_id_t(0, "Radio", 0); uhd::rfnoc::radio_ctrl::sptr radio_ctrl = usrp->get_block_ctrl<uhd::rfnoc::radio_ctrl>(radio_ctrl_id); std::cout << "Radio Control Built" << std::endl; // Set radio Parameters radio_ctrl->set_args("master_clock_rate=" + std::to_string(master_clock_rate) + ",spp=" + std::to_string(spp) ); radio_ctrl->set_rate(rate); radio_ctrl->set_rx_gain(gain, radio_chan); radio_ctrl->set_rx_antenna(ant, radio_chan); radio_ctrl->set_rx_bandwidth(bw, radio_chan); radio_ctrl->set_rx_frequency(freq, radio_chan); std::cout << "Radio parameters set" << std::endl; // allow time for radio setup boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); /************************************************************************ * Graph Setup ***********************************************************************/ // Get Graph boost::shared_ptr<uhd::rfnoc::graph> rx_graph = usrp->create_graph("rx_graph"); std::cout << "rx_graph pointer built" << std::endl; // clear USRP usrp->clear(); // Build Graph // radio ==> window ==> FFT // Window Block: uhd::rfnoc::source_block_ctrl_base::sptr win_block_ctrl; if (!usrp->has_block((std::string) "Window")) { std::cerr << " No Window Block found in this FPGA image\n"; return ~0; } else { win_block_ctrl = usrp->get_block_ctrl<uhd::rfnoc::source_block_ctrl_base>((std::string) "Window"); std::string coeffs = "Coeffs=["; // use uniform window for (size_t i = 0; i < fft_size; i++) { coeffs += "32767,"; } coeffs.replace(coeffs.find_last_of(","), 1, "]"); coeffs += ",spp=" + std::to_string(fft_size); // Connect Block win_block_ctrl->set_args(uhd::device_addr_t(coeffs)); rx_graph->connect(radio_ctrl_id, radio_chan, win_block_ctrl->get_block_id(), uhd::rfnoc::ANY_PORT); } std::cout << "Radio ==> window" << std::endl; // FFT Block uhd::rfnoc::source_block_ctrl_base::sptr fft_block_ctrl; if (!usrp->has_block((std::string) "FFT")) { std::cerr << " No FFT Block found in this FPGA image\n"; return ~0; } else { fft_block_ctrl = usrp->get_block_ctrl<uhd::rfnoc::source_block_ctrl_base>((std::string) "FFT"); fft_block_ctrl->set_args(uhd::device_addr_t("spp=" + std::to_string(fft_size) + ",direction=forward,shift=normal,magnitude_out=COMPLEX")); rx_graph->connect(win_block_ctrl->get_block_id(), fft_block_ctrl->get_block_id()); } std::cout << "Window ==> FFT" << std::endl; /************************************************************************ * Streamer Setup ***********************************************************************/ // Setup streamer std::cout << "making the streamer" << std::endl; uhd::device_addr_t streamer_args((std::string) ""); streamer_args["block_id"] = fft_block_ctrl->get_block_id().to_string(); streamer_args["block_port"] = std::to_string(radio_chan); //Complex float on ARM, Complex Short on FPGA uhd::stream_args_t stream_args("fc32", "sc16"); stream_args.args = streamer_args; boost::shared_ptr<uhd::rx_streamer> rx_stream = usrp->get_rx_stream(stream_args); std::cout << "streamer made" << std::endl; /************************************************************************ * Get Samples ***********************************************************************/ // Prepare to get recv samples std::cout << "prep to get samples" << std::endl; size_t num_rx_samples = 0; uhd::rx_metadata_t md; uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); stream_cmd.num_samps = fft_size; stream_cmd.time_spec = uhd::time_spec_t(); stream_cmd.stream_now = true; std::vector<std::complex<float>> buff(fft_size, 0); // Issue stream_cmd and get samples std::cout << "Getting samples" << std::endl; rx_stream->issue_stream_cmd(stream_cmd); num_rx_samples = rx_stream->recv(&buff.front(), fft_size, md, 1.0, false); if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) { std::cerr << "Recv Error: " << md.strerror() << std::endl; std::cerr << "Num Samp: " << std::to_string(num_rx_samples) << std::endl; } else { std::cout << "Got samples!" << std::endl; std::cout << "Num Samp: " << std::to_string(num_rx_samples) << std::endl; } std::cout << "======================================" << std::endl; /************************************************************************ * Update Graph ***********************************************************************/ // New FFT size and Sample Rate fft_size=256; rate=2.56e6; radio_ctrl->set_rate(rate); std::cout << "radio rate changed" << std::endl; // Reconfigure Graph usrp->clear(); // radio ==> window ==> FFT ==> Packet Resizer // Window Block: std::cout << "resetting window coeffs" << std::endl; std::string coeffs2 = "Coeffs=["; // use uniform window for (size_t i = 0; i < fft_size; i++) { coeffs2 += "32767,"; } coeffs2.replace(coeffs2.find_last_of(","), 1, "]"); coeffs2 += ",spp=" + std::to_string(fft_size); // Connect Block win_block_ctrl->set_args(uhd::device_addr_t(coeffs2)); rx_graph->connect(radio_ctrl_id, radio_chan, win_block_ctrl->get_block_id(), uhd::rfnoc::ANY_PORT); std::cout << "Radio ==> Window" << std::endl; // FFT Block std::cout << "RESETTING FFT" << std::endl; fft_block_ctrl->set_args(uhd::device_addr_t("spp=" + std::to_string(fft_size) + ",direction=forward,shift=normal,magnitude_out=COMPLEX")); rx_graph->connect(win_block_ctrl->get_block_id(), fft_block_ctrl->get_block_id()); std::cout << "Window ==> FFT" << std::endl; // Setup streamer std::cout << "New Streamer" << std::endl; uhd::device_addr_t streamer_args2((std::string) ""); streamer_args2["block_id"] = fft_block_ctrl->get_block_id().to_string(); streamer_args2["block_port"] = std::to_string(radio_chan); //Complex float on ARM, Complex Short on FPGA uhd::stream_args_t stream_args2("fc32", "sc16"); stream_args2.args = streamer_args2; rx_stream = usrp->get_rx_stream(stream_args2); std::cout << "New streamer built" << std::endl; /************************************************************************ * Try Getting More Samples ***********************************************************************/ // Prepare to get recv samples num_rx_samples = 0; md.reset(); uhd::stream_cmd_t stream_cmd2(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); stream_cmd2.num_samps = fft_size; stream_cmd2.time_spec = uhd::time_spec_t(); stream_cmd2.stream_now = true; std::vector<std::complex<float>> buff2(fft_size, 0); // Issue stream_cmd and get samples std::cout << "Getting more samples" << std::endl; rx_stream->issue_stream_cmd(stream_cmd2); num_rx_samples = rx_stream->recv(&buff2.front(), fft_size, md, 1.0, false); if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) { std::cerr << "Recv Error: " << md.strerror() << std::endl; std::cerr << "Num Samp: " << std::to_string(num_rx_samples) << std::endl; } else { std::cout << "Got samples!" << std::endl; std::cout << "Num Samp: " << std::to_string(num_rx_samples) << std::endl; } std::cout << "============================================" << std::endl; std::cout << "Done!!!" << std::endl; return EXIT_SUCCESS; }
_______________________________________________ USRP-users mailing list USRP-users@lists.ettus.com http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com