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(ERROR) << str_code(metadata); } return true; }
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; }
/*********************************************************************** * Check for empty serial **********************************************************************/ void check_for_empty_serial(uhd::usrp::multi_usrp::sptr usrp) { // 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(); //extract eeprom uhd::property_tree::sptr tree = usrp->get_device()->get_tree(); // This only works with transceiver boards, so we can always check rx side const uhd::fs_path db_path = "/mboards/0/dboards/" + subdev_spec[0].db_name + "/rx_eeprom"; const uhd::usrp::dboard_eeprom_t db_eeprom = tree->access<uhd::usrp::dboard_eeprom_t>(db_path).get(); std::string error_string = "This dboard has no serial!\n\nPlease see the Calibration documentation for details on how to fix this."; if (db_eeprom.serial.empty()) throw std::runtime_error(error_string); }
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; }
static inline void test_device( uhd::usrp::multi_usrp::sptr usrp, double rx_rate_sps, double duration_secs ){ const size_t max_samps_per_packet = usrp->get_device()->get_max_recv_samps_per_packet(); std::cout << boost::format("Testing receive rate %f Msps (%f second run)") % (rx_rate_sps/1e6) % duration_secs << std::endl; //allocate recv buffer and metatdata uhd::rx_metadata_t md; std::vector<std::complex<float> > buff(max_samps_per_packet); //flush the buffers in the recv path while(usrp->get_device()->recv( &buff.front(), buff.size(), md, uhd::io_type_t::COMPLEX_FLOAT32, uhd::device::RECV_MODE_ONE_PACKET )){ /* NOP */ }; //declare status variables bool got_first_packet = false; size_t total_recv_packets = 0; size_t total_lost_samples = 0; size_t total_recv_samples = 0; uhd::time_spec_t initial_time_spec; uhd::time_spec_t next_expected_time_spec; usrp->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); do { size_t num_rx_samps = usrp->get_device()->recv( &buff.front(), buff.size(), md, uhd::io_type_t::COMPLEX_FLOAT32, uhd::device::RECV_MODE_ONE_PACKET ); //handle the error codes switch(md.error_code){ case uhd::rx_metadata_t::ERROR_CODE_NONE: case uhd::rx_metadata_t::ERROR_CODE_OVERFLOW: break; default: std::cerr << "Error code: " << md.error_code << std::endl; std::cerr << "Unexpected error on recv, exit test..." << std::endl; return; } if (not md.has_time_spec){ std::cerr << "Metadata missing time spec, exit test..." << std::endl; return; } total_recv_samples += num_rx_samps; total_recv_packets++; if (not got_first_packet){ initial_time_spec = md.time_spec; next_expected_time_spec = initial_time_spec; got_first_packet = true; } double approx_lost_samps = rx_rate_sps*(md.time_spec - next_expected_time_spec).get_real_secs(); total_lost_samples += std::max(0, boost::math::iround(approx_lost_samps)); next_expected_time_spec = md.time_spec + uhd::time_spec_t(0, num_rx_samps, rx_rate_sps); } while((next_expected_time_spec - initial_time_spec) < uhd::time_spec_t(duration_secs)); usrp->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); //print a summary std::cout << std::endl; //go to newline, recv may spew SXSYSZ... std::cout << boost::format(" Received packets: %d") % total_recv_packets << std::endl; std::cout << boost::format(" Received samples: %d") % total_recv_samples << std::endl; std::cout << boost::format(" Lost samples: %d") % total_lost_samples << std::endl; size_t packets_lost = boost::math::iround(double(total_lost_samples)/max_samps_per_packet); std::cout << boost::format(" Lost packets: %d (approximate)") % packets_lost << std::endl; double actual_rx_rate_sps = (total_recv_samples*rx_rate_sps)/(total_recv_samples+total_lost_samples); std::cout << boost::format(" Sustained receive rate: %f Msps") % (actual_rx_rate_sps/1e6) << std::endl; std::cout << std::endl << std::endl; }
int uhd_device::readSamples(float *buf, int len, bool *overrun, TIMESTAMP timestamp, bool *underrun, unsigned *RSSI) { ssize_t rc; uhd::time_spec_t ts; uhd::rx_metadata_t metadata; uint64_t pkt_buf[rx_spp]; if (skip_rx) return 0; // Shift read time with respect to transmit clock timestamp += ts_offset; ts = convert_time(timestamp, actual_smpl_rt); LOG(DEBUG) << "Requested timestamp = " << ts.get_real_secs(); // Check that timestamp is valid rc = rx_smpl_buf->avail_smpls(timestamp); if (rc < 0) { LOG(ERR) << rx_smpl_buf->str_code(rc); LOG(ERR) << rx_smpl_buf->str_status(); return 0; } // Receive samples from the usrp until we have enough while (rx_smpl_buf->avail_smpls(timestamp) < len) { size_t num_smpls = usrp_dev->get_device()->recv( (void*)pkt_buf, rx_spp, metadata, uhd::io_type_t::COMPLEX_FLOAT32, uhd::device::RECV_MODE_ONE_PACKET); rx_pkt_cnt++; // Check for errors rc = check_rx_md_err(metadata, num_smpls); switch (rc) { case ERROR_UNRECOVERABLE: LOG(ALERT) << "UHD: Version " << uhd::get_version_string(); LOG(ALERT) << "UHD: Unrecoverable error, exiting..."; exit(-1); case ERROR_TIMING: restart(prev_ts); case ERROR_UNHANDLED: continue; } ts = metadata.time_spec; LOG(DEBUG) << "Received timestamp = " << ts.get_real_secs(); rc = rx_smpl_buf->write(pkt_buf, num_smpls, metadata.time_spec); // Continue on local overrun, exit on other errors if ((rc < 0)) { LOG(ERR) << rx_smpl_buf->str_code(rc); LOG(ERR) << rx_smpl_buf->str_status(); if (rc != smpl_buf::ERROR_OVERFLOW) return 0; } } // We have enough samples rc = rx_smpl_buf->read(buf, len, timestamp); if ((rc < 0) || (rc != len)) { LOG(ERR) << rx_smpl_buf->str_code(rc); LOG(ERR) << rx_smpl_buf->str_status(); return 0; } return len; }
int UHD_SAFE_MAIN(int argc, char *argv[]){ size_t rx_cnt; rx_cnt = 0; uhd::set_thread_priority_safe(); uhd::time_spec_t refer; po::options_description desc("Allowed options"); desc.add_options() ("help", "help message") ("r0", po::value<string>(&usrp_ip)->default_value("addr=192.168.10.10" ), "usrp's IP") ("in", po::value<string>(&in_name)->default_value("wn_trace/src_data_1.bin"), "binary samples file") ("out", po::value<string>(&out_name)->default_value("wn_trace/recv_signal.bin"), "signal file") ("i", po::value<double>(&inter)->default_value(SAMPLE_P), "interval of two sampling") ("f", po::value<double>(&freq)->default_value(2.49), "RF center frequency in Hz") ("g", po::value<double>(&gain)->default_value(30.0), "gain for the RF chain") ("s", po::value<double>(&r_sec)->default_value(1), "recording seconds") ("c", po::value<size_t>(&r_cnt)->default_value(90), "round count"); po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); if (vm.count("help")){ cout << boost::format("UHD TX samples from file %s") % desc << endl; return ~0; } // Initial systems init_sys(); size_t cleaning, done_cleaning; done_cleaning = 0; cleaning = 0; while(cleaning < ANT_CNT) { if (!done_cleaning) { usrp->get_device()->recv(pkt, SYM_LEN, rx_md, C_FLOAT32, R_ONE_PKT); if(rx_md.time_spec.get_real_secs() >= time_start_recv.get_real_secs()) { done_cleaning = 1; cleaning++; } } // cout << cleaning << "-" << done_cleaning << " Clean ant" << i << " buff:" << rx_md.time_spec.get_real_secs() << endl; } // TODO: // Receive Signals // HINT: You have to receive signals here // How many signals you have to recv? Ans: s_cnt // using rx_cnt+=usrp->get_device()->recv(...) // using pkt to record the received samples // remove content of within while loop cout << endl << "# of recv samples: " << s_cnt << endl; gr_complex *current = pkt; while(rx_cnt < s_cnt) { size_t read_cnt = 80; //At last recv(), modify read_cnt to receive the remaining samples if (s_cnt - rx_cnt < read_cnt){ read_cnt = s_cnt - rx_cnt; } // what is the number of remaining samples? read_cnt = ...; rx_cnt += usrp->get_device()->recv(current, read_cnt, rx_md, C_FLOAT32, R_ONE_PKT); current = current + read_cnt; //rx_cnt is the total number you have received //cout << rx_cnt << " hello " << endl; cout<<abs(*pkt)<<endl<<endl; if (rx_cnt < 100) cout << "Ant" << " recving at " << rx_md.time_spec.get_real_secs() << endl; } stream_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS; usrp->issue_stream_cmd(stream_cmd); boost::this_thread::sleep(boost::posix_time::seconds(1)); //allow for some setup time // End systems dump_signals(); end_sys(); cout << "Terminate systems ... " << endl << endl; return 0; }