template<typename samp_type> void recv_to_file( uhd::usrp::multi_usrp::sptr usrp, const uhd::io_type_t &io_type, const std::string &file, size_t samps_per_buff ){ uhd::rx_metadata_t md; std::vector<samp_type> buff(samps_per_buff); //std::ofstream outfile(file.c_str(), std::ofstream::binary); while(not stop_signal_called){ size_t num_rx_samps = usrp->get_device()->recv( &buff.front(), buff.size(), md, io_type, uhd::device::RECV_MODE_FULL_BUFF ); if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) break; if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE){ break; //throw std::runtime_error(str(boost::format( // "Unexpected error code 0x%x" //) % md.error_code)); } //outfile.write((const char*)&buff.front(), num_rx_samps*sizeof(samp_type)); } //outfile.close(); }
bool uhd_device::flush_recv(size_t num_pkts) { uhd::rx_metadata_t md; size_t num_smpls; uint32_t buff[rx_spp]; float timeout; // Use .01 sec instead of the default .1 sec timeout = .01; for (size_t i = 0; i < num_pkts; i++) { num_smpls = usrp_dev->get_device()->recv( buff, rx_spp, md, uhd::io_type_t::COMPLEX_INT16, uhd::device::RECV_MODE_ONE_PACKET, timeout); if (!num_smpls) { switch (md.error_code) { case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: return true; default: continue; } } } return true; }
/*********************************************************************** * 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(); }
void uhd_device::set_ref_clk(bool ext_clk) { if (ext_clk) usrp_dev->set_clock_source("external"); return; }
/*********************************************************************** * Data capture routine **********************************************************************/ static void capture_samples( uhd::usrp::multi_usrp::sptr usrp, uhd::rx_streamer::sptr rx_stream, std::vector<samp_type > &buff, const size_t nsamps_requested ){ buff.resize(nsamps_requested); 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 = buff.size(); stream_cmd.stream_now = true; usrp->issue_stream_cmd(stream_cmd); const size_t num_rx_samps = rx_stream->recv(&buff.front(), buff.size(), md); //validate the received data if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE){ throw std::runtime_error(str(boost::format( "Receiver error: %s" ) % md.strerror())); } //we can live if all the data didnt come in if (num_rx_samps > buff.size()/2){ buff.resize(num_rx_samps); return; } if (num_rx_samps != buff.size()){ throw std::runtime_error("did not get all the samples requested"); } }
template<typename samp_type> void send_from_file( uhd::usrp::multi_usrp::sptr usrp, const uhd::io_type_t &io_type, const std::string &file, size_t samps_per_buff ){ 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){ 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(); usrp->get_device()->send( &buff.front(), num_tx_samps, md, io_type, uhd::device::SEND_MODE_FULL_BUFF ); } infile.close(); }
void set(const std::vector<Set> sets) const { for(const auto set : sets) { usrp->set_tree_value(set.path, set.value); set.print(); } std::cout << std::endl; }
void check(const std::vector<Set> sets) const { for(const auto set : sets) { std::string value; usrp->get_tree_value(set.path, value); assert(value == set.value); } }
/*********************************************************************** * Set standard defaults for devices **********************************************************************/ static inline void set_optimum_defaults(uhd::usrp::multi_usrp::sptr usrp) { uhd::property_tree::sptr tree = usrp->get_device()->get_tree(); // Will work on 1st subdev, top-level must make sure it's the right one uhd::usrp::subdev_spec_t subdev_spec = usrp->get_rx_subdev_spec(); const uhd::fs_path mb_path = "/mboards/0"; const std::string mb_name = tree->access<std::string>(mb_path / "name").get(); if (mb_name.find("USRP2") != std::string::npos or mb_name.find("N200") != std::string::npos or mb_name.find("N210") != std::string::npos or mb_name.find("X300") != std::string::npos or mb_name.find("X310") != std::string::npos) { usrp->set_tx_rate(12.5e6); usrp->set_rx_rate(12.5e6); } else if (mb_name.find("B100") != std::string::npos) { usrp->set_tx_rate(4e6); usrp->set_rx_rate(4e6); } else { throw std::runtime_error("self-calibration is not supported for this device"); } const uhd::fs_path tx_fe_path = "/mboards/0/dboards/" + subdev_spec[0].db_name + "/tx_frontends/0"; const std::string tx_name = tree->access<std::string>(tx_fe_path / "name").get(); if (tx_name.find("WBX") == std::string::npos and tx_name.find("SBX") == std::string::npos and tx_name.find("CBX") == std::string::npos and tx_name.find("RFX") == std::string::npos and tx_name.find("UBX") == std::string::npos ) { throw std::runtime_error("self-calibration is not supported for this TX dboard"); } usrp->set_tx_gain(0); const uhd::fs_path rx_fe_path = "/mboards/0/dboards/" + subdev_spec[0].db_name + "/rx_frontends/0"; const std::string rx_name = tree->access<std::string>(rx_fe_path / "name").get(); if (rx_name.find("WBX") == std::string::npos and rx_name.find("SBX") == std::string::npos and rx_name.find("CBX") == std::string::npos and rx_name.find("RFX") == std::string::npos and rx_name.find("UBX") == std::string::npos ) { throw std::runtime_error("self-calibration is not supported for this RX dboard"); } usrp->set_rx_gain(0); }
bool uhd_device::stop() { uhd::stream_cmd_t stream_cmd = uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS; usrp_dev->issue_stream_cmd(stream_cmd); started = false; return true; }
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; }
/*********************************************************************** * Tune RX and TX routine **********************************************************************/ static double tune_rx_and_tx( uhd::usrp::multi_usrp::sptr usrp, const double tx_lo_freq, const double rx_offset) { // tune the transmitter with no cordic uhd::tune_request_t tx_tune_req(tx_lo_freq); tx_tune_req.dsp_freq_policy = uhd::tune_request_t::POLICY_MANUAL; tx_tune_req.dsp_freq = 0; usrp->set_tx_freq(tx_tune_req); // tune the receiver double rx_freq = usrp->get_tx_freq() - rx_offset; double min_fe_rx_freq = usrp->get_fe_rx_freq_range().start(); double max_fe_rx_freq = usrp->get_fe_rx_freq_range().stop(); uhd::tune_request_t rx_tune_req(rx_freq); rx_tune_req.dsp_freq_policy = uhd::tune_request_t::POLICY_MANUAL; rx_tune_req.dsp_freq = 0; if (rx_freq < min_fe_rx_freq) rx_tune_req.dsp_freq = rx_freq - min_fe_rx_freq; else if (rx_freq > max_fe_rx_freq) rx_tune_req.dsp_freq = rx_freq - max_fe_rx_freq; usrp->set_rx_freq(rx_tune_req); wait_for_lo_lock(usrp); return usrp->get_tx_freq(); }
std::string return_usrp_config_string(uhd::usrp::multi_usrp::sptr usrp, int chan, bool test_tx, bool test_rx, bool is_b2xx){ uhd::dict<std::string, std::string> tx_info = usrp->get_usrp_tx_info(chan); uhd::dict<std::string, std::string> rx_info = usrp->get_usrp_rx_info(chan); std::string info_string; std::string mboard_id, mboard_serial; std::string tx_serial, tx_subdev_name, tx_subdev_spec; std::string rx_serial, rx_subdev_name, rx_subdev_spec; mboard_id = tx_info.get("mboard_id"); if(tx_info.get("mboard_serial") == "") mboard_serial = "no serial"; else mboard_serial = tx_info.get("mboard_serial"); info_string = str(boost::format("Motherboard: %s (%s)\n") % mboard_id % mboard_serial); if(test_tx){ if(tx_info.get("tx_serial") == "") tx_serial = "no serial"; else tx_serial = tx_info.get("tx_serial"); tx_subdev_name = tx_info.get("tx_subdev_name"); tx_subdev_spec = tx_info.get("tx_subdev_spec"); info_string += is_b2xx ? str(boost::format("TX: %s (%s)") % tx_subdev_name % tx_subdev_spec) : str(boost::format("TX: %s (%s, %s)") % tx_subdev_name % tx_serial % tx_subdev_spec); } if(test_tx and test_rx) info_string += "\n"; if(test_rx){ if(rx_info.get("rx_serial") == "") rx_serial = "no serial"; else rx_serial = rx_info.get("rx_serial"); rx_subdev_name = rx_info.get("rx_subdev_name"); rx_subdev_spec = rx_info.get("rx_subdev_spec"); info_string += is_b2xx ? str(boost::format("RX: %s (%s)") % rx_subdev_name % rx_subdev_spec) : str(boost::format("RX: %s (%s, %s)") % rx_subdev_name % rx_serial % rx_subdev_spec); } return info_string; }
uhd::rx_streamer::sptr Responder::create_rx_streamer(uhd::usrp::multi_usrp::sptr usrp) { uhd::stream_args_t stream_args("fc32"); //complex floats if (_samps_per_packet > 0) { stream_args.args["spp"] = str(boost::format("%d") % _samps_per_packet); } uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args); _samps_per_packet = rx_stream->get_max_num_samps(); return rx_stream; }
/*********************************************************************** * RX Hammer **********************************************************************/ void rx_hammer(uhd::usrp::multi_usrp::sptr usrp, const std::string &rx_cpu, const std::string &rx_otw){ uhd::set_thread_priority_safe(); //create a receive streamer uhd::stream_args_t stream_args(rx_cpu, rx_otw); for (size_t ch = 0; ch < usrp->get_num_mboards(); ch++) //linear channel mapping stream_args.channels.push_back(ch); uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args); //print pre-test summary std::cout << boost::format( "Testing receive rate %f Msps" ) % (usrp->get_rx_rate()/1e6) << std::endl; //setup variables and allocate buffer uhd::rx_metadata_t md; const size_t max_samps_per_packet = rx_stream->get_max_num_samps(); std::vector<char> buff(max_samps_per_packet*uhd::convert::get_bytes_per_item(rx_cpu)); std::vector<void *> buffs; for (size_t ch = 0; ch < stream_args.channels.size(); ch++) buffs.push_back(&buff.front()); //same buffer for each channel bool had_an_overflow = false; uhd::time_spec_t last_time; const double rate = usrp->get_rx_rate(); double timeout = 1; uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); cmd.time_spec = usrp->get_time_now() + uhd::time_spec_t(0.05); cmd.stream_now = (buffs.size() == 1); srand( time(NULL) ); while (not boost::this_thread::interruption_requested()){ cmd.num_samps = rand() % 100000; usrp->issue_stream_cmd(cmd); num_rx_samps += rx_stream->recv(buffs, max_samps_per_packet, md, timeout, true); //handle the error codes switch(md.error_code){ case uhd::rx_metadata_t::ERROR_CODE_NONE: if (had_an_overflow){ had_an_overflow = false; num_dropped_samps += boost::math::iround((md.time_spec - last_time).get_real_secs()*rate); } break; case uhd::rx_metadata_t::ERROR_CODE_OVERFLOW: had_an_overflow = true; last_time = md.time_spec; num_overflows++; break; default: std::cerr << "Error code: " << md.error_code << std::endl; std::cerr << "Unexpected error on recv, continuing..." << std::endl; break; } } }
bool uhd_device::recv_async_msg() { uhd::async_metadata_t metadata; if (!usrp_dev->get_device()->recv_async_msg(metadata)) return false; // Assume that any error requires resynchronization if (metadata.event_code != uhd::async_metadata_t::EVENT_CODE_BURST_ACK) { aligned = false; LOG(ERR) << str_code(metadata); } return true; }
int setup_device(uhd::usrp::multi_usrp::sptr usrp, double rx_gain, double tx_gain, double freq, double rate){ //create a usrp device std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; usrp->set_rx_rate(rate); usrp->set_rx_freq(freq); usrp->set_rx_gain(rx_gain); usrp->set_tx_rate(rate); usrp->set_tx_freq(freq); usrp->set_tx_gain(tx_gain); }
int uhd_device::writeSamples(float *buf, int len, bool *underrun, unsigned long long timestamp,bool isControl) { uhd::tx_metadata_t metadata; metadata.has_time_spec = true; metadata.start_of_burst = false; metadata.end_of_burst = false; metadata.time_spec = convert_time(timestamp, actual_smpl_rt); // No control packets if (isControl) { LOG(ERR) << "Control packets not supported"; return 0; } // Drop a fixed number of packets (magic value) if (!aligned) { drop_cnt++; if (drop_cnt == 1) { LOG(DEBUG) << "Aligning transmitter: stop burst"; *underrun = true; metadata.end_of_burst = true; } else if (drop_cnt < 30) { LOG(DEBUG) << "Aligning transmitter: packet advance"; return len; } else { LOG(DEBUG) << "Aligning transmitter: start burst"; metadata.start_of_burst = true; aligned = true; drop_cnt = 0; } } size_t num_smpls = usrp_dev->get_device()->send(buf, len, metadata, uhd::io_type_t::COMPLEX_FLOAT32, uhd::device::SEND_MODE_FULL_BUFF); if (num_smpls != (unsigned) len) { LOG(ALERT) << "UHD: Device send timed out"; LOG(ALERT) << "UHD: Version " << uhd::get_version_string(); LOG(ALERT) << "UHD: Unrecoverable error, exiting..."; exit(-1); } return num_smpls; }
int uhd_device::set_master_clk(double clk_rate) { double actual, offset, limit = 1.0; try { usrp_dev->set_master_clock_rate(clk_rate); } catch (const std::exception &ex) { LOG(ALERT) << "UHD clock rate setting failed: " << clk_rate; LOG(ALERT) << ex.what(); return -1; } actual = usrp_dev->get_master_clock_rate(); offset = fabs(clk_rate - actual); if (offset > limit) { LOG(ALERT) << "Failed to set master clock rate"; LOG(ALERT) << "Requested clock rate " << clk_rate; LOG(ALERT) << "Actual clock rate " << actual; return -1; } return 0; }
/*********************************************************************** * 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 uhd_device::set_ref_clk(bool ext_clk) { uhd::clock_config_t clk_cfg; clk_cfg.pps_source = uhd::clock_config_t::PPS_SMA; if (ext_clk) clk_cfg.ref_source = uhd::clock_config_t::REF_SMA; else clk_cfg.ref_source = uhd::clock_config_t::REF_INT; usrp_dev->set_clock_config(clk_cfg); return; }
bool uhd_device::stop() { if (!started) return false; started = false; uhd::stream_cmd_t stream_cmd = uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS; usrp_dev->issue_stream_cmd(stream_cmd); delete async_event_thrd; return true; }
template<typename samp_type> void recv_to_file( uhd::usrp::multi_usrp::sptr usrp, const uhd::io_type_t &io_type, std::ofstream &outfile, size_t samps_per_buff, uhd::time_spec_t send_time ){ uhd::rx_metadata_t md; std::vector<samp_type> buff(samps_per_buff); //a packet has 362 samples send_time = send_time + uhd::time_spec_t(1.0); uhd::time_spec_t front_time, end_time; int index; size_t num_rx_samps = usrp->get_device()->recv( &buff.front(), buff.size(), md, io_type, // uhd::device::RECV_MODE_FULL_BUFF uhd::device::RECV_MODE_ONE_PACKET ); if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) return; if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE){ throw std::runtime_error(str(boost::format( "Unexpected error code 0x%x" ) % md.error_code)); } front_time = md.time_spec; end_time = md.time_spec + uhd::time_spec_t((double)(num_rx_samps-1)*decimation/100.0e6); //outfile.write((const char*)&buff.front(), num_rx_samps*sizeof(samp_type)); if((send_time-front_time).get_real_secs() < 0 && (end_time-send_time).get_real_secs() >=0 ){ outfile.write((const char*)&buff.front(), num_rx_samps*sizeof(samp_type)); }else{ if( (send_time-front_time).get_real_secs() >=0 && (end_time-send_time).get_real_secs() >=0 ){ index = (send_time-front_time).get_frac_secs()/((double)decimation/100.0e6); outfile.write((const char*)&buff.at(index), (num_rx_samps-index)*sizeof(samp_type)); printf("start to save at %f with index %d, send_time %f \n",front_time.get_real_secs(),index,send_time.get_real_secs()); printf("timestamp %f tick %ld\n",(front_time+uhd::time_spec_t((double)index*(double)decimation/100.0e6)).get_real_secs(), (front_time+uhd::time_spec_t((double)index*(double)decimation/100.0e6)).get_tick_count(100e6)); } } }
bool uhd_device::recv_async_msg() { uhd::async_metadata_t md; if (!usrp_dev->get_device()->recv_async_msg(md)) return false; // Assume that any error requires resynchronization if (md.event_code != uhd::async_metadata_t::EVENT_CODE_BURST_ACK) { aligned = false; if ((md.event_code != uhd::async_metadata_t::EVENT_CODE_UNDERFLOW) && (md.event_code != uhd::async_metadata_t::EVENT_CODE_TIME_ERROR)) { LOG(ERR) << str_code(md); } } return true; }
// Check function for GPS LOCKED sensor from the Ettus GPSDO bool check_gps_locked(uhd::usrp::multi_usrp::sptr usrp) { try { uhd::sensor_value_t sensor_value( usrp->get_mboard_sensor("gps_locked", 0)); if (not sensor_value.to_bool()) { etiLog.level(warn) << "OutputUHD: gps_locked " << sensor_value.to_pp_string(); return false; } return true; } catch (uhd::lookup_error &e) { etiLog.level(warn) << "OutputUHD: no gps_locked sensor"; return false; } }
// Check function for GPS TIMELOCK sensor from the ODR LEA-M8F board GPSDO bool check_gps_timelock(uhd::usrp::multi_usrp::sptr usrp) { try { std::string sensor_value( usrp->get_mboard_sensor("gps_timelock", 0).to_pp_string()); if (sensor_value.find("TIME LOCKED") == std::string::npos) { etiLog.level(warn) << "OutputUHD: gps_timelock " << sensor_value; return false; } return true; } catch (uhd::lookup_error &e) { etiLog.level(warn) << "OutputUHD: no gps_timelock sensor"; return false; } }
void init_usrp() { cout << "Initial USRP" << endl; usrp = uhd::usrp::multi_usrp::make(usrp_ip); usrp->set_rx_rate(rate); usrp->set_tx_rate(rate); usrp->set_rx_freq(freq); usrp->set_tx_freq(freq); usrp->set_rx_gain(gain); uhd::meta_range_t rx_range = usrp->get_rx_gain_range(); }
/*! * Test the late command message: * Issue a stream command with a time that is in the past. * We expect to get an inline late command message. */ bool test_late_command_message(uhd::usrp::multi_usrp::sptr usrp, uhd::rx_streamer::sptr rx_stream, uhd::tx_streamer::sptr){ std::cout << "Test late command message... " << std::flush; usrp->set_time_now(uhd::time_spec_t(200.0)); //set time uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); stream_cmd.num_samps = rx_stream->get_max_num_samps(); stream_cmd.stream_now = false; stream_cmd.time_spec = uhd::time_spec_t(100.0); //time in the past rx_stream->issue_stream_cmd(stream_cmd); std::vector<std::complex<float> > buff(rx_stream->get_max_num_samps()); uhd::rx_metadata_t md; const size_t nsamps = rx_stream->recv( &buff.front(), buff.size(), md ); switch(md.error_code){ case uhd::rx_metadata_t::ERROR_CODE_LATE_COMMAND: std::cout << boost::format( "success:\n" " Got error code late command message.\n" ) << std::endl; return true; case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: std::cout << boost::format( "failed:\n" " Inline message recv timed out.\n" ) << std::endl; return false; default: std::cout << boost::format( "failed:\n" " Got unexpected error code 0x%x, nsamps %u.\n" ) % md.error_code % nsamps << std::endl; return false; } }
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; }