/*********************************************************************** * Transmit thread **********************************************************************/ static void tx_thread(uhd::usrp::multi_usrp::sptr usrp, const double tx_wave_freq, const double tx_wave_ampl) { uhd::set_thread_priority_safe(); // set max TX gain usrp->set_tx_gain(usrp->get_tx_gain_range().stop()); //create a transmit streamer uhd::stream_args_t stream_args("fc32"); //complex floats uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); //setup variables and allocate buffer uhd::tx_metadata_t md; md.has_time_spec = false; std::vector<samp_type> buff(tx_stream->get_max_num_samps()*10); //values for the wave table lookup size_t index = 0; const double tx_rate = usrp->get_tx_rate(); const size_t step = boost::math::iround(wave_table_len * tx_wave_freq / tx_rate); wave_table table(tx_wave_ampl); //fill buff and send until interrupted while (not boost::this_thread::interruption_requested()) { for (size_t i = 0; i < buff.size(); i++) buff[i] = table(index += step); tx_stream->send(&buff.front(), buff.size(), md); } //send a mini EOB packet md.end_of_burst = true; tx_stream->send("", 0, md); }
/*********************************************************************** * Transmit thread **********************************************************************/ static void tx_thread(uhd::usrp::multi_usrp::sptr usrp, const double tx_wave_ampl) { uhd::set_thread_priority_safe(); //create a transmit streamer uhd::stream_args_t stream_args("fc32"); //complex floats uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); //setup variables and allocate buffer uhd::tx_metadata_t md; md.has_time_spec = false; std::vector<samp_type> buff(tx_stream->get_max_num_samps()*10); //fill buff and send until interrupted while (not boost::this_thread::interruption_requested()) { for (size_t i = 0; i < buff.size(); i++) buff[i] = float(tx_wave_ampl); tx_stream->send(&buff.front(), buff.size(), md); } //send a mini EOB packet md.end_of_burst = true; tx_stream->send("", 0, md); }
template<typename samp_type> void send_from_file( uhd::usrp::multi_usrp::sptr usrp, const std::string &cpu_format, const std::string &wire_format, const std::string &file, size_t samps_per_buff ){ //create a transmit streamer uhd::stream_args_t stream_args(cpu_format, wire_format); uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); uhd::tx_metadata_t md; md.start_of_burst = false; md.end_of_burst = false; std::vector<samp_type> buff(samps_per_buff); std::ifstream infile(file.c_str(), std::ifstream::binary); //loop until the entire file has been read while(not md.end_of_burst and not stop_signal_called){ infile.read((char*)&buff.front(), buff.size()*sizeof(samp_type)); size_t num_tx_samps = infile.gcount()/sizeof(samp_type); md.end_of_burst = infile.eof(); tx_stream->send(&buff.front(), num_tx_samps, md); } infile.close(); }
uhd::tx_streamer::sptr Responder::create_tx_streamer(uhd::usrp::multi_usrp::sptr usrp) { uhd::stream_args_t tx_stream_args("fc32"); //complex floats if (_allow_late_bursts == false) { tx_stream_args.args["underflow_policy"] = "next_burst"; } uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(tx_stream_args); return tx_stream; }
/*********************************************************************** * TX Hammer **********************************************************************/ void tx_hammer(uhd::usrp::multi_usrp::sptr usrp, const std::string &tx_cpu, const std::string &tx_otw){ uhd::set_thread_priority_safe(); //create a transmit streamer uhd::stream_args_t stream_args(tx_cpu, tx_otw); for (size_t ch = 0; ch < usrp->get_num_mboards(); ch++) //linear channel mapping stream_args.channels.push_back(ch); uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); uhd::tx_metadata_t md; std::vector<std::complex<float> > buff(10000); //print pre-test summary std::cout << boost::format( "Testing transmit rate %f Msps" ) % (usrp->get_tx_rate()/1e6) << std::endl; //setup variables and allocate buffer std::srand( time(NULL) ); while(not boost::this_thread::interruption_requested()){ size_t total_num_samps = rand() % 100000; size_t num_acc_samps = 0; float timeout = 1; usrp->set_time_now(uhd::time_spec_t(0.0)); while(num_acc_samps < total_num_samps){ //send a single packet num_tx_samps += tx_stream->send(&buff, tx_stream->get_max_num_samps(), md, timeout); num_acc_samps += std::min(total_num_samps-num_acc_samps, tx_stream->get_max_num_samps()); } //send a mini EOB packet md.end_of_burst = true; tx_stream->send("", 0, md); } }
int uhd_device::open(const std::string &args, bool extref) { // Find UHD devices uhd::device_addr_t addr(args); uhd::device_addrs_t dev_addrs = uhd::device::find(addr); if (dev_addrs.size() == 0) { LOG(ALERT) << "No UHD devices found with address '" << args << "'"; return -1; } // Use the first found device LOG(INFO) << "Using discovered UHD device " << dev_addrs[0].to_string(); try { usrp_dev = uhd::usrp::multi_usrp::make(dev_addrs[0]); } catch(...) { LOG(ALERT) << "UHD make failed, device " << dev_addrs[0].to_string(); return -1; } // Check for a valid device type and set bus type if (!parse_dev_type()) return -1; if (extref) set_ref_clk(true); // Create TX and RX streamers uhd::stream_args_t stream_args("sc16"); tx_stream = usrp_dev->get_tx_stream(stream_args); rx_stream = usrp_dev->get_rx_stream(stream_args); // Number of samples per over-the-wire packet tx_spp = tx_stream->get_max_num_samps(); rx_spp = rx_stream->get_max_num_samps(); // Set rates double _tx_rate = select_rate(dev_type, sps); double _rx_rate = _tx_rate / sps; if ((_tx_rate > 0.0) && (set_rates(_tx_rate, _rx_rate) < 0)) return -1; // Create receive buffer size_t buf_len = SAMPLE_BUF_SZ / sizeof(uint32_t); rx_smpl_buf = new smpl_buf(buf_len, rx_rate); // Set receive chain sample offset double offset = get_dev_offset(dev_type, sps); if (offset == 0.0) { LOG(ERR) << "Unsupported configuration, no correction applied"; ts_offset = 0; } else { ts_offset = (TIMESTAMP) (offset * rx_rate); } // Initialize and shadow gain values init_gains(); // Print configuration LOG(INFO) << "\n" << usrp_dev->get_pp_string(); switch (dev_type) { case B100: return RESAMP_64M; case USRP2: case X3XX: return RESAMP_100M; } return NORMAL; }