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

Reply via email to