At the very benign 20 MS/s, I'd really say your first option is the way to go. The rest probably won't work very well du to turn on/off behaviour requiring you to zero pad a bit to flush your TX data chains.
You can of course also write an RFNoC block to store and generate data in-FPGA, but really: at 20MS/s just continously stream. Even a bog- normal Gigabit Ethernet card has plenty enough bandwidth to do that. I doubt sending a sequence from RAM will occupy much CPU on your host PC. Best regards, Marcus On Thu, 2019-07-18 at 22:58 +0200, Cédric Hannotier via USRP-users wrote: > Dear all, > > I would like to periodically send a frame with an USRP X310 (frame > length: 320 samples, rate: 20 MS/s, period: 1-500 ms). However, I > struggle to find the best way to implement it. What I have tried so > far: > > 1. Append zeros to the frame to reach the expected period. > However, > this consumes too much bandwidth due to the zeros. > > 2. Use tx_streamer->send() with a tx_metadata_t.time_spec and > tx_streamer->recv_async_msg(). Using that, only the frame is sent, > saving most of the bandwidth. However, with small periods, it tends > to > print some 'L'. > > 3. Buffer a batch of send request on the USRP, then wait a > specific > time (using eg. recv_async_msg() until the returned metadata > contains > the penultimate time_spec (I expect that the time_spec returned is > the > one specified in the send metadata)) and redo. The issue is that I > was > not able to find the buffer size (is it related to the > tx_streamer->get_max_num_samps()?). I would like to fill the buffer > without overflow. > > I was hoping that I could save the frame in an USRP's memory, and > then > ask it to periodically send the frame with a specific period. Is it > possible? > > Here is an example of (2): > > template <typename samp_type> > void send_from_file(const uhd::usrp::multi_usrp::sptr &usrp, > uhd::tx_streamer::sptr tx_stream, const > std::string& > file, > const double period) > { > size_t data_size = get_file_size<samp_type>(file); > std::ifstream infile(file, std::ifstream::binary); > std::vector<samp_type> buff(data_size); > infile.read(reinterpret_cast<char*>(buff.data()), > (std::streamsize)(buff.size()*sizeof(samp_type))); > infile.close(); > size_t num_tx_samps = buff.size(); > std::cout << file << " " << buff[0] << " " << num_tx_samps << > std::endl; > > uhd::tx_metadata_t md; > md.start_of_burst = true; > md.end_of_burst = true; > md.has_time_spec = true; > md.time_spec = usrp->get_time_last_pps()+5.; > double timeout = md.time_spec.get_real_secs(); > uhd::async_metadata_t md_status; > > while (not stop_signal_called) { > tx_stream->send(&buff.front(), num_tx_samps, md); > if (tx_stream->recv_async_msg(md_status, timeout)) { > if (md_status.event_code != > uhd::async_metadata_t::event_code_t::EVENT_CODE_BURST_ACK) { > std::cerr << "Error: " << md_status.event_code > << std::endl; > exit(EXIT_FAILURE); > } > } else { > std::cerr << "timeout before sent" << std::endl; > exit(EXIT_FAILURE); > } > > timeout = 0.1; > md.time_spec += period; > } > } > > > > Best Regards, > Cédric > > _______________________________________________ > USRP-users mailing list > USRP-users@lists.ettus.com > http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com _______________________________________________ USRP-users mailing list USRP-users@lists.ettus.com http://lists.ettus.com/mailman/listinfo/usrp-users_lists.ettus.com