int uhd_device::set_rates(double tx_rate, double rx_rate) { double offset_limit = 1.0; double tx_offset, rx_offset; // B2XX is the only device where we set FPGA clocking if (dev_type == B2XX) { if (set_master_clk(B2XX_CLK_RT) < 0) return -1; } // Set sample rates try { usrp_dev->set_tx_rate(tx_rate); usrp_dev->set_rx_rate(rx_rate); } catch (const std::exception &ex) { LOG(ALERT) << "UHD rate setting failed"; LOG(ALERT) << ex.what(); return -1; } this->tx_rate = usrp_dev->get_tx_rate(); this->rx_rate = usrp_dev->get_rx_rate(); tx_offset = fabs(this->tx_rate - tx_rate); rx_offset = fabs(this->rx_rate - rx_rate); if ((tx_offset > offset_limit) || (rx_offset > offset_limit)) { LOG(ALERT) << "Actual sample rate differs from desired rate"; LOG(ALERT) << "Tx/Rx (" << this->tx_rate << "/" << this->rx_rate << ")"; return -1; } return 0; }
/*********************************************************************** * 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); }
/*********************************************************************** * TX Hammer **********************************************************************/ void tx_hammer(uhd::usrp::multi_usrp::sptr usrp, const std::string &tx_cpu, uhd::tx_streamer::sptr tx_stream){ uhd::set_thread_priority_safe(); uhd::tx_metadata_t md; const size_t max_samps_per_packet = tx_stream->get_max_num_samps(); std::vector<char> buff(max_samps_per_packet*uhd::convert::get_bytes_per_item(tx_cpu)); std::vector<void *> buffs; for (size_t ch = 0; ch < tx_stream->get_num_channels(); ch++) buffs.push_back(&buff.front()); //same buffer for each channel //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(buffs, max_samps_per_packet, 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); } }
/*********************************************************************** * Benchmark TX Rate **********************************************************************/ void benchmark_tx_rate( uhd::usrp::multi_usrp::sptr usrp, const std::string &tx_cpu, uhd::tx_streamer::sptr tx_stream, std::atomic<bool>& burst_timer_elapsed, const boost::posix_time::ptime &start_time, bool random_nsamps=false ) { uhd::set_thread_priority_safe(); //print pre-test summary std::cout << boost::format( "[%s] Testing transmit rate %f Msps on %u channels" ) % NOW() % (usrp->get_tx_rate()/1e6) % tx_stream->get_num_channels() << std::endl; //setup variables and allocate buffer uhd::tx_metadata_t md; md.time_spec = usrp->get_time_now() + uhd::time_spec_t(INIT_DELAY); md.has_time_spec = (tx_stream->get_num_channels() > 1); const size_t max_samps_per_packet = tx_stream->get_max_num_samps(); std::vector<char> buff(max_samps_per_packet*uhd::convert::get_bytes_per_item(tx_cpu)); std::vector<const void *> buffs; for (size_t ch = 0; ch < tx_stream->get_num_channels(); ch++) buffs.push_back(&buff.front()); //same buffer for each channel md.has_time_spec = (buffs.size() != 1); if (random_nsamps) { std::srand((unsigned int)time(NULL)); while (not burst_timer_elapsed) { size_t total_num_samps = rand() % max_samps_per_packet; size_t num_acc_samps = 0; const 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(buffs, max_samps_per_packet, md, timeout)*tx_stream->get_num_channels(); num_acc_samps += std::min(total_num_samps-num_acc_samps, tx_stream->get_max_num_samps()); } } } else { while (not burst_timer_elapsed) { const size_t num_tx_samps_sent_now = tx_stream->send(buffs, max_samps_per_packet, md)*tx_stream->get_num_channels(); num_tx_samps += num_tx_samps_sent_now; if (num_tx_samps_sent_now == 0) { num_timeouts_tx++; if ((num_timeouts_tx % 10000) == 1) { std::cerr << "[" << NOW() << "] Tx timeouts: " << num_timeouts_tx << std::endl; } } md.has_time_spec = false; } } //send a mini EOB packet md.end_of_burst = true; tx_stream->send(buffs, 0, md); }
double uhd_device::set_rates(double rate) { double actual_rt, actual_clk_rt; #if !defined(MULTICHAN) & !defined(RESAMPLE) // Make sure we can set the master clock rate on this device actual_clk_rt = usrp_dev->get_master_clock_rate(); if (actual_clk_rt > U1_DEFAULT_CLK_RT) { LOG(ALERT) << "Cannot set clock rate on this device"; LOG(ALERT) << "Please compile with host resampling support"; return -1.0; } // Set master clock rate usrp_dev->set_master_clock_rate(master_clk_rt); actual_clk_rt = usrp_dev->get_master_clock_rate(); if (actual_clk_rt != master_clk_rt) { LOG(ALERT) << "Failed to set master clock rate"; LOG(ALERT) << "Actual clock rate " << actual_clk_rt; return -1.0; } #endif // Set sample rates usrp_dev->set_tx_rate(rate); usrp_dev->set_rx_rate(rate); actual_rt = usrp_dev->get_tx_rate(); if (actual_rt != rate) { LOG(ALERT) << "Actual sample rate differs from desired rate"; LOG(ALERT) << actual_rt << "Hz"; return -1.0; } if (usrp_dev->get_rx_rate() != actual_rt) { LOG(ALERT) << "Transmit and receive sample rates do not match"; return -1.0; } return actual_rt; }
/*********************************************************************** * 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); } }
void get_tx_parameters(uhd::usrp::multi_usrp::sptr usrp, size_t mboard, std::ostream & os) { using namespace std; namespace radio = uhd::usrp; size_t nchan = 0; // CONFIGURATION SUB_DEVICE os << std::endl << "********** TX Sub Device ***********" << std::endl; // Get sub device specification os << std::endl << "-----> Get TX Subdevice" << std::endl; try { os << "TX Subdevice Specification: "; radio::subdev_spec_t tx_subdev = usrp->get_tx_subdev_spec(mboard); os << tx_subdev.to_pp_string() << endl; } catch(uhd::runtime_error &e) { os << " Exception occurred : " << e.code() << endl; } // Number of tx channels os << std::endl << "-----> Get number of TX channels" << std::endl; try { size_t num_tx = usrp->get_tx_num_channels(); os << "Number of TX channels: " ; os << num_tx << endl; } catch (uhd::runtime_error &e) { os << " Exception occurred : " << e.code() << endl; } // TX Device Name os << std::endl << "-----> Get TX Subdevice Name" << std::endl; try { os << "TX Subdevice Name: "; string tx_name = usrp->get_tx_subdev_name(nchan); os << tx_name << endl; } catch (uhd::runtime_error &e) { os << " Exception occurred : " << e.code() << endl; } // TX SAMPLE RATE os << std::endl << "********** TX Sample Rate ***********" << std::endl; // Get Current TX rate os << std::endl << "-----> Get TX Rate" << std::endl; try { os << "TX Rate: " ; double tx_rate = usrp->get_tx_rate(nchan); os << tx_rate << endl; } catch (uhd::runtime_error &e) { os << " Exception occurred : " << e.code() << endl; } // Get list of TX rates os << std::endl << "-----> Get TX Rate List" << std::endl; try { os << "TX Rate List: " ; uhd::meta_range_t tx_rates = usrp->get_tx_rates(nchan); os << "Start: " << tx_rates.start() << " Stop: " << tx_rates.stop() << " Step: " << tx_rates.step() << endl; os << tx_rates.to_pp_string() << endl; } catch (uhd::runtime_error &e) { os << " Exception occurred : " << e.code() << endl; } // TX FREQUENCIES os << std::endl << "********** TX Frequencies ***********" << std::endl; // Current TX frequency os << std::endl << "-----> Get TX Center Frequency" << std::endl; try { os << "TX Freq: "; double tx_freq = usrp->get_tx_freq(nchan); os << tx_freq << endl; } catch (uhd::runtime_error &e) { os << " Exception occurred : " << e.code() << endl; } // TX Frequency Range os << std::endl << "-----> Get TX Center Frequency Range" << std::endl; try { os << "TX Frequency Range: "; uhd::freq_range_t tx_freq_range = usrp->get_tx_freq_range(nchan); os << "Start: " << tx_freq_range.start() << " Stop: " << tx_freq_range.stop() << " Step: " << tx_freq_range.step() << endl; os << tx_freq_range.to_pp_string() << endl; } catch (uhd::runtime_error &e) { os << " Exception occurred : " << e.code() << endl; } // Front end TX frequency range os << std::endl << "-----> Get TX RF Front End Center Frequency Range" << std::endl; try { os << "TX Front End Frequency Range: "; uhd::freq_range_t tx_fe_freq_range = usrp->get_fe_tx_freq_range(nchan); os << "Start: " << tx_fe_freq_range.start() << " Stop: " << tx_fe_freq_range.stop() << " Step: " << tx_fe_freq_range.step() << endl; os << tx_fe_freq_range.to_pp_string() << endl; } catch (uhd::runtime_error &e) { os << " Exception occurred : " << e.code() << endl; } // TX GAIN os << std::endl << "********** TX Gain ***********" << std::endl; // Total combined gain os << endl << "-----> Get TX Total Gain" << endl; os << "TX Total Gain: " ; try { double tx_total_gain = usrp->get_tx_gain(nchan); os << tx_total_gain << endl; } catch(uhd::runtime_error &e) { os << "Exception code: " << e.code() << endl; } // List of all gain elements os << std::endl << "-----> Get TX gain names" << std::endl; std::vector<std::string> tx_gain_names = usrp->get_tx_gain_names(nchan); os << "Tx Gain Names: " << std::endl; for (int index =0; index < tx_gain_names.size(); index++) { // Name os << "\t" << tx_gain_names[index] << endl; } for (int index =0; index < tx_gain_names.size(); index++) { // Name os << "\t" << "Name: " << tx_gain_names[index] << " Value: "; // Value try { double element_gain = usrp->get_tx_gain(tx_gain_names[index], nchan); os << element_gain << endl; } catch(uhd::runtime_error &e) { os << "Exception code while getting value: " << e.code() << endl; } } // Gain ranges for each of the gain elements os << std::endl << "-----> Get TX element gain ranges" << std::endl; for (int index =0; index < tx_gain_names.size(); index++) { // Name os << "\t" << "Name: " << tx_gain_names[index] << " Value: "; // Value try { uhd::gain_range_t element_gain_range = usrp->get_tx_gain_range(tx_gain_names[index], nchan); os << "Start: " << element_gain_range.start() << " End: " << element_gain_range.stop() << " Step: " << element_gain_range.step() << endl; } catch(uhd::runtime_error &e) { os << "Exception code while getting value: " << e.code() << endl; } } // Total Gain range try { os << endl << "-----> Get TX Total Gain Range" << endl; uhd::gain_range_t tx_total_gain_range = usrp->get_tx_gain_range(nchan); os << "TX Total Gain Range: " ; os << "Start: " << tx_total_gain_range.start() << " End: " << tx_total_gain_range.stop() << " Step: " << tx_total_gain_range.step() << endl; } catch(uhd::runtime_error &e) { os << "Exception code: " << e.code() <<endl; } // ANTENNA FUNCTIONS os << std::endl << "********** TX ANTENNA ***********" << std::endl; // Current Tx Antenna os << std::endl << "-----> Get TX Antenna" << std::endl; try { os << "TX Antenna: " ; string tx_antenna = usrp->get_tx_antenna(nchan); os << tx_antenna << endl; } catch(uhd::runtime_error &e) { os << "Exception code: " << e.code() <<endl; } // TX Antenna choices os << std::endl << "-----> Get Tx Antenna List" << std::endl; try { os << "TX Antennas : " << std::endl; std::vector<std::string> tx_antennas = usrp->get_tx_antennas(nchan); for (int index =0; index < tx_antennas.size(); index++) os << "\t" << tx_antennas[index] << std::endl; } catch(uhd::runtime_error &e) { os << "Exception code: " << e.code() <<endl; } // TX BANDWIDTH FUNCTIONS os << std::endl << "********** TX BANDWIDTH ***********" << std::endl; // Current TX Bandwidth os << endl << "-----> Get TX Bandwidth" << endl; try { os << "TX Bandwidth " ; double tx_bandwidth = usrp->get_tx_bandwidth(nchan); os << tx_bandwidth << endl; } catch (uhd::runtime_error &e) { os << "Exception occured " << e.code() << endl; } // TX Bandwidth Range os << endl << "-----> Get TX Bandwidth Range" << endl; try { os << "TX Bandwidth Range: " ; uhd::gain_range_t tx_bandwidth_range = usrp->get_tx_bandwidth_range(nchan); os << "Start: " << tx_bandwidth_range .start() << " End: " << tx_bandwidth_range .stop() << " Step: " << tx_bandwidth_range .step() << endl; } catch(uhd::runtime_error &e) { os << "Exception code: " << e.code() <<endl; } // TX DBOARD INTERFACE OBJECT os << std::endl << "********** TX DBOARD INTERFACE ***********" << std::endl; // TX Dboard Interface os << endl << "-----> Get tx_dboard_iface()" << endl; try { os << "TX Dboard Interface " ; uhd::usrp::dboard_iface::sptr tx_dboard_iface = usrp->get_tx_dboard_iface(nchan); os << tx_dboard_iface << endl; } catch (uhd::runtime_error &e) { os << "Exception occured " << e.code() << endl; } // TX _SENSORS os << std::endl << "********** TX Sensors ***********" << std::endl; // List of all available sensors os << std::endl << "-----> Get TX Sensors Name" << std::endl; std::vector<std::string> tx_sensor_names = usrp->get_tx_sensor_names(nchan); os << "Sensor Names: " << std::endl; for (int index =0; index < tx_sensor_names.size(); index++) { // Name os << "\t" << tx_sensor_names[index] << ": "; // Value try { uhd::sensor_value_t tx_sensor_value = usrp->get_tx_sensor(tx_sensor_names[index], nchan); os << tx_sensor_value.to_pp_string()<< std::endl; } catch(uhd::runtime_error &e) { os << "Exception occured " << e.code() << endl; } } }