int UHD_SAFE_MAIN(int argc, char *argv[]){ uhd::set_thread_priority_safe(); //variables to be set by po std::string args, file, type, ant, subdev, ref, wirefmt; size_t total_num_samps, spb; double rate, freq, gain, bw, total_time, setup_time; //setup the program options po::options_description desc("Allowed options"); desc.add_options() ("help", "help message") ("args", po::value<std::string>(&args)->default_value(""), "multi uhd device address args") ("file", po::value<std::string>(&file)->default_value("usrp_samples.dat"), "name of the file to write binary samples to") ("type", po::value<std::string>(&type)->default_value("short"), "sample type: double, float, or short") ("nsamps", po::value<size_t>(&total_num_samps)->default_value(0), "total number of samples to receive") ("duration", po::value<double>(&total_time)->default_value(0), "total number of seconds to receive") ("time", po::value<double>(&total_time), "(DEPRECATED) will go away soon! Use --duration instead") ("spb", po::value<size_t>(&spb)->default_value(10000), "samples per buffer") ("rate", po::value<double>(&rate)->default_value(1e6), "rate of incoming samples") ("freq", po::value<double>(&freq)->default_value(0.0), "RF center frequency in Hz") ("gain", po::value<double>(&gain), "gain for the RF chain") ("ant", po::value<std::string>(&ant), "antenna selection") ("subdev", po::value<std::string>(&subdev), "subdevice specification") ("bw", po::value<double>(&bw), "analog frontend filter bandwidth in Hz") ("ref", po::value<std::string>(&ref)->default_value("internal"), "reference source (internal, external, mimo)") ("wirefmt", po::value<std::string>(&wirefmt)->default_value("sc16"), "wire format (sc8 or sc16)") ("setup", po::value<double>(&setup_time)->default_value(1.0), "seconds of setup time") ("progress", "periodically display short-term bandwidth") ("stats", "show average bandwidth on exit") ("sizemap", "track packet size and display breakdown on exit") ("null", "run without writing to file") ("continue", "don't abort on a bad packet") ("skip-lo", "skip checking LO lock status") ("int-n", "tune USRP with integer-N tuning") ; po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); //print the help message if (vm.count("help")) { std::cout << boost::format("UHD RX samples to file %s") % desc << std::endl; std::cout << std::endl << "This application streams data from a single channel of a USRP device to a file.\n" << std::endl; return ~0; } bool bw_summary = vm.count("progress") > 0; bool stats = vm.count("stats") > 0; bool null = vm.count("null") > 0; bool enable_size_map = vm.count("sizemap") > 0; bool continue_on_bad_packet = vm.count("continue") > 0; if (enable_size_map) std::cout << "Packet size tracking enabled - will only recv one packet at a time!" << std::endl; //create a usrp device std::cout << std::endl; std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args); //Lock mboard clocks usrp->set_clock_source(ref); //always select the subdevice first, the channel mapping affects the other settings if (vm.count("subdev")) usrp->set_rx_subdev_spec(subdev); std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; //set the sample rate if (rate <= 0.0){ std::cerr << "Please specify a valid sample rate" << std::endl; return ~0; } std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate/1e6) << std::endl; usrp->set_rx_rate(rate); std::cout << boost::format("Actual RX Rate: %f Msps...") % (usrp->get_rx_rate()/1e6) << std::endl << std::endl; //set the center frequency if (vm.count("freq")) { //with default of 0.0 this will always be true std::cout << boost::format("Setting RX Freq: %f MHz...") % (freq/1e6) << std::endl; uhd::tune_request_t tune_request(freq); if(vm.count("int-n")) tune_request.args = uhd::device_addr_t("mode_n=integer"); usrp->set_rx_freq(tune_request); std::cout << boost::format("Actual RX Freq: %f MHz...") % (usrp->get_rx_freq()/1e6) << std::endl << std::endl; } //set the rf gain if (vm.count("gain")) { std::cout << boost::format("Setting RX Gain: %f dB...") % gain << std::endl; usrp->set_rx_gain(gain); std::cout << boost::format("Actual RX Gain: %f dB...") % usrp->get_rx_gain() << std::endl << std::endl; } //set the IF filter bandwidth if (vm.count("bw")) { std::cout << boost::format("Setting RX Bandwidth: %f MHz...") % bw << std::endl; usrp->set_rx_bandwidth(bw); std::cout << boost::format("Actual RX Bandwidth: %f MHz...") % usrp->get_rx_bandwidth() << std::endl << std::endl; } //set the antenna if (vm.count("ant")) usrp->set_rx_antenna(ant); boost::this_thread::sleep(boost::posix_time::seconds(setup_time)); //allow for some setup time //check Ref and LO Lock detect if (not vm.count("skip-lo")){ check_locked_sensor(usrp->get_rx_sensor_names(0), "lo_locked", boost::bind(&uhd::usrp::multi_usrp::get_rx_sensor, usrp, _1, 0), setup_time); if (ref == "mimo") check_locked_sensor(usrp->get_mboard_sensor_names(0), "mimo_locked", boost::bind(&uhd::usrp::multi_usrp::get_mboard_sensor, usrp, _1, 0), setup_time); if (ref == "external") check_locked_sensor(usrp->get_mboard_sensor_names(0), "ref_locked", boost::bind(&uhd::usrp::multi_usrp::get_mboard_sensor, usrp, _1, 0), setup_time); } if (total_num_samps == 0){ std::signal(SIGINT, &sig_int_handler); std::cout << "Press Ctrl + C to stop streaming..." << std::endl; } #define recv_to_file_args(format) \ (usrp, format, wirefmt, file, spb, total_num_samps, total_time, bw_summary, stats, null, enable_size_map, continue_on_bad_packet) //recv to file if (type == "double") recv_to_file<std::complex<double> >recv_to_file_args("fc64"); else if (type == "float") recv_to_file<std::complex<float> >recv_to_file_args("fc32"); else if (type == "short") recv_to_file<std::complex<short> >recv_to_file_args("sc16"); else throw std::runtime_error("Unknown type " + type); //finished std::cout << std::endl << "Done!" << std::endl << std::endl; return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { uint32_t i,j, fault; std::string args; args="addr=192.168.10.2"; // create USRP device uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args); // init USRP usrp->set_clock_source("internal"); if (verbose) std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; // setup tx sample rate and frequency usrp->set_tx_rate(TX_SAMPLE_RATE); uhd::tune_request_t tune_request(TX_FREQ); usrp->set_tx_freq(tune_request, CHANNEL); usrp->set_tx_gain(TX_GAIN, CHANNEL); // create a transmit streamer uhd::stream_args_t stream_args("fc32"); stream_args.channels = channel_nums; uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); // allocate buffer with data const size_t spb = tx_stream->get_max_num_samps(); std::vector<std::complex<float> > buff(spb, std::complex<float>(ampl, ampl)); // setup RXFE gpio usrp->set_gpio_attr("RXA", "CTRL", RXFE_CONTROL, RXFE_MASK); // set GPIO to manual control usrp->set_gpio_attr("RXA", "DDR", RXFE_MASK, RXFE_MASK); // set everybody as outputs // setup control gpio usrp->set_gpio_attr("TXA", "CTRL", CONTROL_CONTROL, CONTROL_MASK); // set GPIO to manual control usrp->set_gpio_attr("TXA", "DDR", CONTROL_TR_MASK, CONTROL_TR_MASK); // set TR as outputs usrp->set_gpio_attr("TXA", "DDR", 0x00, CONTROL_FAULT_MASK); // set fault as input // start up with rxfe disabled, rx mode usrp->set_gpio_attr("RXA", "OUT", 0x00, RXFE_AMP_MASK); usrp->set_gpio_attr("RXA", "OUT", 0xFF, RXFE_ATT_MASK); usrp->set_gpio_attr("TXA", "OUT", CONTROL_RX, CONTROL_TR_MASK); // reset the clock to 0 usrp->set_time_now(uhd::time_spec_t(0.0)); // cycle through dio settings while(1) { for(j = 0; j < 4; j++) { usrp->set_gpio_attr("RXA", "OUT", j << 6, RXFE_AMP_MASK); for(i = 0; i < 32; i++) { fault = (usrp->get_gpio_attr("TXA", "READBACK") & CONTROL_FAULT_MASK); usrp->set_gpio_attr("RXA", "OUT", i, RXFE_ATT_MASK); if(i % 2) { usrp->set_gpio_attr("TXA", "OUT", CONTROL_RX, CONTROL_TR_MASK); } else { usrp->set_gpio_attr("TXA", "OUT", CONTROL_TX, CONTROL_TR_MASK); } printf("fault state: %d, att state: %d, tx state %d\n", fault, i, i % 2); sleep(1); } } } return 0; }
int UHD_SAFE_MAIN(int argc, char *argv[]){ uhd::set_thread_priority_safe(); //variables to be set by po std::string args, ant, subdev, ref; size_t num_bins; double rate, freq, gain, bw, frame_rate; float ref_lvl, dyn_rng; //setup the program options po::options_description desc("Allowed options"); desc.add_options() ("help", "help message") ("args", po::value<std::string>(&args)->default_value(""), "multi uhd device address args") // hardware parameters ("rate", po::value<double>(&rate), "rate of incoming samples (sps)") ("freq", po::value<double>(&freq), "RF center frequency in Hz") ("gain", po::value<double>(&gain), "gain for the RF chain") ("ant", po::value<std::string>(&ant), "daughterboard antenna selection") ("subdev", po::value<std::string>(&subdev), "daughterboard subdevice specification") ("bw", po::value<double>(&bw), "daughterboard IF filter bandwidth in Hz") // display parameters ("num-bins", po::value<size_t>(&num_bins)->default_value(512), "the number of bins in the DFT") ("frame-rate", po::value<double>(&frame_rate)->default_value(5), "frame rate of the display (fps)") ("ref-lvl", po::value<float>(&ref_lvl)->default_value(0), "reference level for the display (dB)") ("dyn-rng", po::value<float>(&dyn_rng)->default_value(60), "dynamic range for the display (dB)") ("ref", po::value<std::string>(&ref)->default_value("internal"), "waveform type (internal, external, mimo)") ("int-n", "tune USRP with integer-N tuning") ; po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); //print the help message if (vm.count("help") or not vm.count("rate")){ std::cout << boost::format("UHD RX ASCII Art DFT %s") % desc << std::endl; return EXIT_FAILURE; } //create a usrp device std::cout << std::endl; std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args); //Lock mboard clocks usrp->set_clock_source(ref); //always select the subdevice first, the channel mapping affects the other settings if (vm.count("subdev")) usrp->set_rx_subdev_spec(subdev); std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; //set the sample rate if (not vm.count("rate")){ std::cerr << "Please specify the sample rate with --rate" << std::endl; return EXIT_FAILURE; } std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate/1e6) << std::endl; usrp->set_rx_rate(rate); std::cout << boost::format("Actual RX Rate: %f Msps...") % (usrp->get_rx_rate()/1e6) << std::endl << std::endl; //set the center frequency if (not vm.count("freq")){ std::cerr << "Please specify the center frequency with --freq" << std::endl; return EXIT_FAILURE; } std::cout << boost::format("Setting RX Freq: %f MHz...") % (freq/1e6) << std::endl; uhd::tune_request_t tune_request(freq); if(vm.count("int-n")) tune_request.args = uhd::device_addr_t("mode_n=integer"); usrp->set_rx_freq(tune_request); std::cout << boost::format("Actual RX Freq: %f MHz...") % (usrp->get_rx_freq()/1e6) << std::endl << std::endl; //set the rf gain if (vm.count("gain")){ std::cout << boost::format("Setting RX Gain: %f dB...") % gain << std::endl; usrp->set_rx_gain(gain); std::cout << boost::format("Actual RX Gain: %f dB...") % usrp->get_rx_gain() << std::endl << std::endl; } //set the IF filter bandwidth if (vm.count("bw")){ std::cout << boost::format("Setting RX Bandwidth: %f MHz...") % bw << std::endl; usrp->set_rx_bandwidth(bw); std::cout << boost::format("Actual RX Bandwidth: %f MHz...") % usrp->get_rx_bandwidth() << std::endl << std::endl; } //set the antenna if (vm.count("ant")) usrp->set_rx_antenna(ant); boost::this_thread::sleep(boost::posix_time::seconds(1)); //allow for some setup time //Check Ref and LO Lock detect std::vector<std::string> sensor_names; sensor_names = usrp->get_rx_sensor_names(0); if (std::find(sensor_names.begin(), sensor_names.end(), "lo_locked") != sensor_names.end()) { uhd::sensor_value_t lo_locked = usrp->get_rx_sensor("lo_locked",0); std::cout << boost::format("Checking RX: %s ...") % lo_locked.to_pp_string() << std::endl; UHD_ASSERT_THROW(lo_locked.to_bool()); } sensor_names = usrp->get_mboard_sensor_names(0); if ((ref == "mimo") and (std::find(sensor_names.begin(), sensor_names.end(), "mimo_locked") != sensor_names.end())) { uhd::sensor_value_t mimo_locked = usrp->get_mboard_sensor("mimo_locked",0); std::cout << boost::format("Checking RX: %s ...") % mimo_locked.to_pp_string() << std::endl; UHD_ASSERT_THROW(mimo_locked.to_bool()); } if ((ref == "external") and (std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end())) { uhd::sensor_value_t ref_locked = usrp->get_mboard_sensor("ref_locked",0); std::cout << boost::format("Checking RX: %s ...") % ref_locked.to_pp_string() << std::endl; UHD_ASSERT_THROW(ref_locked.to_bool()); } //create a receive streamer uhd::stream_args_t stream_args("fc32"); //complex floats uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args); //allocate recv buffer and metatdata uhd::rx_metadata_t md; std::vector<std::complex<float> > buff(num_bins); //------------------------------------------------------------------ //-- Initialize //------------------------------------------------------------------ initscr(); //curses init rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); boost::system_time next_refresh = boost::get_system_time(); //------------------------------------------------------------------ //-- Main loop //------------------------------------------------------------------ while (true){ //read a buffer's worth of samples every iteration size_t num_rx_samps = rx_stream->recv( &buff.front(), buff.size(), md ); if (num_rx_samps != buff.size()) continue; //check and update the display refresh condition if (boost::get_system_time() < next_refresh) continue; next_refresh = boost::get_system_time() + boost::posix_time::microseconds(long(1e6/frame_rate)); //calculate the dft and create the ascii art frame acsii_art_dft::log_pwr_dft_type lpdft( acsii_art_dft::log_pwr_dft(&buff.front(), num_rx_samps) ); std::string frame = acsii_art_dft::dft_to_plot( lpdft, COLS, LINES, usrp->get_rx_rate(), usrp->get_rx_freq(), dyn_rng, ref_lvl ); //curses screen handling: clear and print frame clear(); printw("%s", frame.c_str()); //curses key handling: no timeout, any key to exit timeout(0); int ch = getch(); if (ch != KEY_RESIZE and ch != ERR) break; } //------------------------------------------------------------------ //-- Cleanup //------------------------------------------------------------------ rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); endwin(); //curses done //finished std::cout << std::endl << "Done!" << std::endl << std::endl; return EXIT_SUCCESS; }
int UHD_SAFE_MAIN(int argc, char* argv[]) { uhd::set_thread_priority_safe(); // variables to be set by po std::string args, file, format, ant, subdev, ref, wirefmt, streamargs, radio_args, block_id, block_args; size_t total_num_samps, spb, radio_id, radio_chan; double rate, freq, gain, bw, total_time, setup_time; // setup the program options po::options_description desc("Allowed options"); // clang-format off desc.add_options() ("help", "help message") ("file", po::value<std::string>(&file)->default_value("usrp_samples.dat"), "name of the file to write binary samples to") ("format", po::value<std::string>(&format)->default_value("sc16"), "File sample format: sc16, fc32, or fc64") ("duration", po::value<double>(&total_time)->default_value(0), "total number of seconds to receive") ("nsamps", po::value<size_t>(&total_num_samps)->default_value(0), "total number of samples to receive") ("spb", po::value<size_t>(&spb)->default_value(10000), "samples per buffer") ("streamargs", po::value<std::string>(&streamargs)->default_value(""), "stream args") ("progress", "periodically display short-term bandwidth") ("stats", "show average bandwidth on exit") ("sizemap", "track packet size and display breakdown on exit") ("null", "run without writing to file") ("continue", "don't abort on a bad packet") ("args", po::value<std::string>(&args)->default_value(""), "USRP device address args") ("setup", po::value<double>(&setup_time)->default_value(1.0), "seconds of setup time") ("radio-id", po::value<size_t>(&radio_id)->default_value(0), "Radio ID to use (0 or 1).") ("radio-chan", po::value<size_t>(&radio_chan)->default_value(0), "Radio channel") ("radio-args", po::value<std::string>(&radio_args), "Radio channel") ("rate", po::value<double>(&rate)->default_value(1e6), "RX rate of the radio block") ("freq", po::value<double>(&freq)->default_value(0.0), "RF center frequency in Hz") ("gain", po::value<double>(&gain), "gain for the RF chain") ("ant", po::value<std::string>(&ant), "antenna selection") ("bw", po::value<double>(&bw), "analog frontend filter bandwidth in Hz") ("ref", po::value<std::string>(&ref), "reference source (internal, external, mimo)") ("skip-lo", "skip checking LO lock status") ("int-n", "tune USRP with integer-N tuning") ("block-id", po::value<std::string>(&block_id)->default_value(""), "If block ID is specified, this block is inserted between radio and host.") ("block-args", po::value<std::string>(&block_args)->default_value(""), "These args are passed straight to the block.") ; // clang-format on po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); // print the help message if (vm.count("help")) { std::cout << boost::format("UHD/RFNoC RX samples to file %s") % desc << std::endl; std::cout << std::endl << "This application streams data from a single channel of a USRP " "device to a file.\n" << std::endl; return ~0; } bool bw_summary = vm.count("progress") > 0; bool stats = vm.count("stats") > 0; if (vm.count("null") > 0) { file = ""; } bool enable_size_map = vm.count("sizemap") > 0; bool continue_on_bad_packet = vm.count("continue") > 0; if (enable_size_map) { std::cout << "Packet size tracking enabled - will only recv one packet at a time!" << std::endl; } if (format != "sc16" and format != "fc32" and format != "fc64") { std::cout << "Invalid sample format: " << format << std::endl; return EXIT_FAILURE; } /************************************************************************ * Create device and block controls ***********************************************************************/ std::cout << std::endl; std::cout << boost::format("Creating the USRP device with: %s...") % args << std::endl; uhd::device3::sptr usrp = uhd::device3::make(args); // Create handle for radio object uhd::rfnoc::block_id_t radio_ctrl_id(0, "Radio", radio_id); // This next line will fail if the radio is not actually available uhd::rfnoc::radio_ctrl::sptr radio_ctrl = usrp->get_block_ctrl<uhd::rfnoc::radio_ctrl>(radio_ctrl_id); std::cout << "Using radio " << radio_id << ", channel " << radio_chan << std::endl; /************************************************************************ * Set up radio ***********************************************************************/ radio_ctrl->set_args(radio_args); if (vm.count("ref")) { std::cout << "TODO -- Need to implement API call to set clock source." << std::endl; // Lock mboard clocks TODO // usrp->set_clock_source(ref); } // set the sample rate if (rate <= 0.0) { std::cerr << "Please specify a valid sample rate" << std::endl; return EXIT_FAILURE; } std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate / 1e6) << std::endl; radio_ctrl->set_rate(rate); std::cout << boost::format("Actual RX Rate: %f Msps...") % (radio_ctrl->get_rate() / 1e6) << std::endl << std::endl; // set the center frequency if (vm.count("freq")) { std::cout << boost::format("Setting RX Freq: %f MHz...") % (freq / 1e6) << std::endl; uhd::tune_request_t tune_request(freq); if (vm.count("int-n")) { // tune_request.args = uhd::device_addr_t("mode_n=integer"); TODO } radio_ctrl->set_rx_frequency(freq, radio_chan); std::cout << boost::format("Actual RX Freq: %f MHz...") % (radio_ctrl->get_rx_frequency(radio_chan) / 1e6) << std::endl << std::endl; } // set the rf gain if (vm.count("gain")) { std::cout << boost::format("Setting RX Gain: %f dB...") % gain << std::endl; radio_ctrl->set_rx_gain(gain, radio_chan); std::cout << boost::format("Actual RX Gain: %f dB...") % radio_ctrl->get_rx_gain(radio_chan) << std::endl << std::endl; } // set the IF filter bandwidth if (vm.count("bw")) { // std::cout << boost::format("Setting RX Bandwidth: %f MHz...") % (bw/1e6) << // std::endl; radio_ctrl->set_rx_bandwidth(bw, radio_chan); // TODO std::cout << // boost::format("Actual RX Bandwidth: %f MHz...") % // (radio_ctrl->get_rx_bandwidth(radio_chan)/1e6) << std::endl << std::endl; } // set the antenna if (vm.count("ant")) { radio_ctrl->set_rx_antenna(ant, radio_chan); } std::this_thread::sleep_for(std::chrono::milliseconds(int64_t(1000 * setup_time))); // check Ref and LO Lock detect if (not vm.count("skip-lo")) { // TODO // check_locked_sensor(usrp->get_rx_sensor_names(0), "lo_locked", // boost::bind(&uhd::usrp::multi_usrp::get_rx_sensor, usrp, _1, radio_id), // setup_time); if (ref == "external") // check_locked_sensor(usrp->get_mboard_sensor_names(0), "ref_locked", // boost::bind(&uhd::usrp::multi_usrp::get_mboard_sensor, usrp, _1, radio_id), // setup_time); } size_t spp = radio_ctrl->get_arg<int>("spp"); /************************************************************************ * Set up streaming ***********************************************************************/ uhd::device_addr_t streamer_args(streamargs); uhd::rfnoc::graph::sptr rx_graph = usrp->create_graph("rfnoc_rx_to_file"); usrp->clear(); // Set the stream args on the radio: if (block_id.empty()) { // If no extra block is required, connect to the radio: streamer_args["block_id"] = radio_ctrl_id.to_string(); streamer_args["block_port"] = str(boost::format("%d") % radio_chan); } else { // Otherwise, see if the requested block exists and connect it to the radio: if (not usrp->has_block(block_id)) { std::cout << "Block does not exist on current device: " << block_id << std::endl; return EXIT_FAILURE; } uhd::rfnoc::source_block_ctrl_base::sptr blk_ctrl = usrp->get_block_ctrl<uhd::rfnoc::source_block_ctrl_base>(block_id); if (not block_args.empty()) { // Set the block args on the other block: blk_ctrl->set_args(uhd::device_addr_t(block_args)); } // Connect: std::cout << "Connecting " << radio_ctrl_id << " ==> " << blk_ctrl->get_block_id() << std::endl; rx_graph->connect( radio_ctrl_id, radio_chan, blk_ctrl->get_block_id(), uhd::rfnoc::ANY_PORT); streamer_args["block_id"] = blk_ctrl->get_block_id().to_string(); spp = blk_ctrl->get_args().cast<size_t>("spp", spp); } // create a receive streamer std::cout << "Samples per packet: " << spp << std::endl; uhd::stream_args_t stream_args( format, "sc16"); // We should read the wire format from the blocks stream_args.args = streamer_args; stream_args.args["spp"] = boost::lexical_cast<std::string>(spp); std::cout << "Using streamer args: " << stream_args.args.to_string() << std::endl; uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args); if (total_num_samps == 0) { std::signal(SIGINT, &sig_int_handler); std::cout << "Press Ctrl + C to stop streaming..." << std::endl; } #define recv_to_file_args() \ (rx_stream, \ file, \ spb, \ rate, \ total_num_samps, \ total_time, \ bw_summary, \ stats, \ enable_size_map, \ continue_on_bad_packet) // recv to file if (format == "fc64") recv_to_file<std::complex<double>> recv_to_file_args(); else if (format == "fc32") recv_to_file<std::complex<float>> recv_to_file_args(); else if (format == "sc16") recv_to_file<std::complex<short>> recv_to_file_args(); else throw std::runtime_error("Unknown data format: " + format); // finished std::cout << std::endl << "Done!" << std::endl << std::endl; return EXIT_SUCCESS; }
/******************************************************************************* * Main function ******************************************************************************/ int UHD_SAFE_MAIN(int argc, char *argv[]){ uhd::set_thread_priority_safe(); /** Constant Decalartions *************************************************/ const INT32U time = DURATION*(SAMPRATE/SPB); /** Variable Declarations *************************************************/ // (circular) receive buffers std::vector< CINT16 > ch0_rxbuff(time*SPB); // Ch 0 is RX2-A std::vector< CINT16 > ch1_rxbuff(time*SPB); // Ch 1 is RX2-B // Vector of pointers to sectons of rx_buff std::vector< std::vector< CINT16 *> > rxbuffs(time*2, std::vector< CINT16 *>(2)); // Holds the number of received samples returned by rx_stream->recv() INT16U num_rx_samps; // Counters INT16U i = 0,j = 0,k = 0; // Generic counters INT32U write_ctr = 0; // Counts loops through main while() /** Variable Initializations **********************************************/ // Initialise rxbuffs (Vector of pointers) for(i = 0; i < time; i++){ rxbuffs[i][0] = &ch0_rxbuff.front() + SPB * i; rxbuffs[i][1] = &ch1_rxbuff.front() + SPB * i; } /** Main code *************************************************************/ // set USRP Rx params uhd::usrp::multi_usrp::sptr usrp_rx = uhd::usrp::multi_usrp::make(std::string("")); // create a usrp device uhd::tune_request_t tune_request(CARRIERFREQ); // validate tune request usrp_rx->set_master_clock_rate(CLOCKRATE); // set clock rate usrp_rx->set_clock_source(std::string("internal")); // lock mboard clocks // usrp_rx->set_time_source("external"); // Use external reference clock usrp_rx->set_rx_subdev_spec(std::string("A:A A:B")); // select the subdevice usrp_rx->set_rx_rate(SAMPRATE,0); // set the sample rate (Ch 0) usrp_rx->set_rx_rate(SAMPRATE,1); // set the sample rate (Ch 1) usrp_rx->set_rx_freq(tune_request,0); // set the center frequency (Ch 0) usrp_rx->set_rx_freq(tune_request,1); // set the center frequency (Ch 1) usrp_rx->set_rx_gain(RXGAIN,0); // set the rf gain (Ch 0) usrp_rx->set_rx_gain(RXGAIN,1); // set the rf gain (Ch 1) usrp_rx->set_rx_antenna(std::string("TX/RX"),0); // set the antenna (Ch 0) usrp_rx->set_rx_antenna(std::string("TX/RX"),1); // set the antenna (Ch 1) boost::this_thread::sleep(boost::posix_time::seconds(1.0)); // allow for some setup time // check Ref and LO Lock detect for Rx check_locked_sensor(usrp_rx->get_rx_sensor_names(0), "lo_locked", boost::bind(&uhd::usrp::multi_usrp::get_rx_sensor, usrp_rx, _1, 0), 1.0); // create a receive streamer uhd::stream_args_t stream_args_rx("sc16", "sc16"); stream_args_rx.channels = boost::assign::list_of(0)(1); uhd::rx_streamer::sptr rx_stream = usrp_rx->get_rx_stream(stream_args_rx); uhd::rx_metadata_t md_rx; // report stuff to user (things which may differ from what was requested) std::cout << boost::format("Actual RX Rate: %f Msps...") % (usrp_rx->get_rx_rate()/1e6) << std::endl; // set sigint so user can terminate via Ctrl-C std::signal(SIGINT, &sig_int_handler); std::cout << boost::format("Recording RX CH 0 and CH 1 for %i seconds") % DURATION << std::endl << std::endl; std::cout << "Press Enter to start recording..." << std::endl << std::endl; // Wait for "ENTER" key to be pressed while(std::cin.get() != '\n'){} std::cout << "Press Ctrl + C to stop recording..." << std::endl; // setup receive streaming uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); stream_cmd.stream_now = false; stream_cmd.time_spec = uhd::time_spec_t(0.25)+usrp_rx->get_time_now(); // tell USRP to start streaming 0.25 seconds in the future rx_stream->issue_stream_cmd(stream_cmd); // grab initial block of received samples from USRP with nice long timeout (gets discarded) num_rx_samps = rx_stream->recv(rxbuffs[0], SPB, md_rx, 3.0); while(not stop_signal_called){ // grab block of received samples from USRP num_rx_samps = rx_stream->recv(rxbuffs[write_ctr], SPB, md_rx); // Increment counter write_ctr++; // Check if full time has passed if(write_ctr == time){ break; }else{} // Report progress to terminal std::cout << boost::format("\r\t%2i Percent Complete ") % (write_ctr*100/time) << std::flush; } /** while(not stop_signal_called) *************************************/ // Report progress to terminal std::cout << "\r\tdone! " << std::endl << std::endl; if(stop_signal_called){ std::cout << std::endl << "Writing partial buffers to file (this may take awhile)..." << std::endl; }else{ // Write buffers to file std::cout << "Writing buffers to file (this may take awhile)..." << std::endl; } std::cout << " Channel 0 (RX2-A)..." << std::flush; writebuff("./RX2-A.dat", &ch0_rxbuff.front(), write_ctr*SPB); std::cout << "done!" << std::endl; std::cout << " Channel 1 (RX2-B)..." << std::flush; writebuff("./RX2-B.dat", &ch1_rxbuff.front(), write_ctr*SPB); std::cout << "done!" << std::endl; return EXIT_SUCCESS; } /** main() ****************************************************************/
/*********************************************************************** * Main function **********************************************************************/ int UHD_SAFE_MAIN(int argc, char *argv[]){ uhd::set_thread_priority_safe(); //variables to be set by po std::string args, wave_type, ant, subdev, ref, pps, otw, channel_list; uint64_t total_num_samps, spb; double rate, freq, gain, wave_freq, bw; float ampl; //setup the program options po::options_description desc("Allowed options"); desc.add_options() ("help", "help message") ("args", po::value<std::string>(&args)->default_value(""), "single uhd device address args") ("spb", po::value<uint64_t>(&spb)->default_value(0), "samples per buffer, 0 for default") ("nsamps", po::value<uint64_t>(&total_num_samps)->default_value(0), "total number of samples to transmit") ("rate", po::value<double>(&rate), "rate of outgoing samples") ("freq", po::value<double>(&freq), "RF center frequency in Hz") ("ampl", po::value<float>(&l)->default_value(float(0.3)), "amplitude of the waveform [0 to 0.7]") ("gain", po::value<double>(&gain), "gain for the RF chain") ("ant", po::value<std::string>(&ant), "antenna selection") ("subdev", po::value<std::string>(&subdev), "subdevice specification") ("bw", po::value<double>(&bw), "analog frontend filter bandwidth in Hz") ("wave-type", po::value<std::string>(&wave_type)->default_value("CONST"), "waveform type (CONST, SQUARE, RAMP, SINE)") ("wave-freq", po::value<double>(&wave_freq)->default_value(0), "waveform frequency in Hz") ("ref", po::value<std::string>(&ref)->default_value("internal"), "clock reference (internal, external, mimo, gpsdo)") ("pps", po::value<std::string>(&pps), "PPS source (internal, external, mimo, gpsdo)") ("otw", po::value<std::string>(&otw)->default_value("sc16"), "specify the over-the-wire sample mode") ("channels", po::value<std::string>(&channel_list)->default_value("0"), "which channels to use (specify \"0\", \"1\", \"0,1\", etc)") ("int-n", "tune USRP with integer-N tuning") ; po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); //print the help message if (vm.count("help")){ std::cout << boost::format("UHD TX Waveforms %s") % desc << std::endl; return ~0; } //create a usrp device std::cout << std::endl; std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args); //detect which channels to use std::vector<std::string> channel_strings; std::vector<size_t> channel_nums; boost::split(channel_strings, channel_list, boost::is_any_of("\"',")); for(size_t ch = 0; ch < channel_strings.size(); ch++){ size_t chan = boost::lexical_cast<int>(channel_strings[ch]); if(chan >= usrp->get_tx_num_channels()) throw std::runtime_error("Invalid channel(s) specified."); else channel_nums.push_back(boost::lexical_cast<int>(channel_strings[ch])); } //Lock mboard clocks usrp->set_clock_source(ref); //always select the subdevice first, the channel mapping affects the other settings if (vm.count("subdev")) usrp->set_tx_subdev_spec(subdev); std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; //set the sample rate if (not vm.count("rate")){ std::cerr << "Please specify the sample rate with --rate" << std::endl; return ~0; } std::cout << boost::format("Setting TX Rate: %f Msps...") % (rate/1e6) << std::endl; usrp->set_tx_rate(rate); std::cout << boost::format("Actual TX Rate: %f Msps...") % (usrp->get_tx_rate()/1e6) << std::endl << std::endl; //set the center frequency if (not vm.count("freq")){ std::cerr << "Please specify the center frequency with --freq" << std::endl; return ~0; } for(size_t ch = 0; ch < channel_nums.size(); ch++) { std::cout << boost::format("Setting TX Freq: %f MHz...") % (freq/1e6) << std::endl; uhd::tune_request_t tune_request(freq); if(vm.count("int-n")) tune_request.args = uhd::device_addr_t("mode_n=integer"); usrp->set_tx_freq(tune_request, channel_nums[ch]); std::cout << boost::format("Actual TX Freq: %f MHz...") % (usrp->get_tx_freq(channel_nums[ch])/1e6) << std::endl << std::endl; //set the rf gain if (vm.count("gain")){ std::cout << boost::format("Setting TX Gain: %f dB...") % gain << std::endl; usrp->set_tx_gain(gain, channel_nums[ch]); std::cout << boost::format("Actual TX Gain: %f dB...") % usrp->get_tx_gain(channel_nums[ch]) << std::endl << std::endl; } //set the analog frontend filter bandwidth if (vm.count("bw")){ std::cout << boost::format("Setting TX Bandwidth: %f MHz...") % bw << std::endl; usrp->set_tx_bandwidth(bw, channel_nums[ch]); std::cout << boost::format("Actual TX Bandwidth: %f MHz...") % usrp->get_tx_bandwidth(channel_nums[ch]) << std::endl << std::endl; } //set the antenna if (vm.count("ant")) usrp->set_tx_antenna(ant, channel_nums[ch]); } boost::this_thread::sleep(boost::posix_time::seconds(1)); //allow for some setup time //for the const wave, set the wave freq for small samples per period if (wave_freq == 0 and wave_type == "CONST"){ wave_freq = usrp->get_tx_rate()/2; } //error when the waveform is not possible to generate if (std::abs(wave_freq) > usrp->get_tx_rate()/2){ throw std::runtime_error("wave freq out of Nyquist zone"); } if (usrp->get_tx_rate()/std::abs(wave_freq) > wave_table_len/2){ throw std::runtime_error("wave freq too small for table"); } //pre-compute the waveform values const wave_table_class wave_table(wave_type, ampl); const size_t step = boost::math::iround(wave_freq/usrp->get_tx_rate() * wave_table_len); size_t index = 0; //create a transmit streamer //linearly map channels (index0 = channel0, index1 = channel1, ...) uhd::stream_args_t stream_args("fc32", otw); stream_args.channels = channel_nums; uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); //allocate a buffer which we re-use for each channel if (spb == 0) spb = tx_stream->get_max_num_samps()*10; std::vector<std::complex<float> > buff(spb); std::vector<std::complex<float> *> buffs(channel_nums.size(), &buff.front()); std::cout << boost::format("Setting device timestamp to 0...") << std::endl; if (channel_nums.size() > 1) { // Sync times if (pps == "mimo") { UHD_ASSERT_THROW(usrp->get_num_mboards() == 2); //make mboard 1 a slave over the MIMO Cable usrp->set_time_source("mimo", 1); //set time on the master (mboard 0) usrp->set_time_now(uhd::time_spec_t(0.0), 0); //sleep a bit while the slave locks its time to the master boost::this_thread::sleep(boost::posix_time::milliseconds(100)); } else { if (pps == "internal" or pps == "external" or pps == "gpsdo") usrp->set_time_source(pps); usrp->set_time_unknown_pps(uhd::time_spec_t(0.0)); boost::this_thread::sleep(boost::posix_time::seconds(1)); //wait for pps sync pulse } } else { usrp->set_time_now(0.0); } //Check Ref and LO Lock detect std::vector<std::string> sensor_names; const size_t tx_sensor_chan = channel_list.empty() ? 0 : boost::lexical_cast<size_t>(channel_list[0]); sensor_names = usrp->get_tx_sensor_names(tx_sensor_chan); if (std::find(sensor_names.begin(), sensor_names.end(), "lo_locked") != sensor_names.end()) { uhd::sensor_value_t lo_locked = usrp->get_tx_sensor("lo_locked", tx_sensor_chan); std::cout << boost::format("Checking TX: %s ...") % lo_locked.to_pp_string() << std::endl; UHD_ASSERT_THROW(lo_locked.to_bool()); } const size_t mboard_sensor_idx = 0; sensor_names = usrp->get_mboard_sensor_names(mboard_sensor_idx); if ((ref == "mimo") and (std::find(sensor_names.begin(), sensor_names.end(), "mimo_locked") != sensor_names.end())) { uhd::sensor_value_t mimo_locked = usrp->get_mboard_sensor("mimo_locked", mboard_sensor_idx); std::cout << boost::format("Checking TX: %s ...") % mimo_locked.to_pp_string() << std::endl; UHD_ASSERT_THROW(mimo_locked.to_bool()); } if ((ref == "external") and (std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end())) { uhd::sensor_value_t ref_locked = usrp->get_mboard_sensor("ref_locked", mboard_sensor_idx); std::cout << boost::format("Checking TX: %s ...") % ref_locked.to_pp_string() << std::endl; UHD_ASSERT_THROW(ref_locked.to_bool()); } std::signal(SIGINT, &sig_int_handler); std::cout << "Press Ctrl + C to stop streaming..." << std::endl; // Set up metadata. We start streaming a bit in the future // to allow MIMO operation: uhd::tx_metadata_t md; md.start_of_burst = true; md.end_of_burst = false; md.has_time_spec = true; md.time_spec = usrp->get_time_now() + uhd::time_spec_t(0.1); //send data until the signal handler gets called //or if we accumulate the number of samples specified (unless it's 0) uint64_t num_acc_samps = 0; while(true){ if (stop_signal_called) break; if (total_num_samps > 0 and num_acc_samps >= total_num_samps) break; //fill the buffer with the waveform for (size_t n = 0; n < buff.size(); n++){ buff[n] = wave_table(index += step); } //send the entire contents of the buffer num_acc_samps += tx_stream->send( buffs, buff.size(), md ); md.start_of_burst = false; md.has_time_spec = false; } //send a mini EOB packet md.end_of_burst = true; tx_stream->send("", 0, md); //finished std::cout << std::endl << "Done!" << std::endl << std::endl; return EXIT_SUCCESS; }
void uhdInput::setVFOFrequency (int32_t freq) { std::cout << boost::format ("Setting RX Freq: %f MHz...") % (freq/1e6) << std::endl; uhd::tune_request_t tune_request (freq); m_usrp->set_rx_freq (tune_request); }
int UHD_SAFE_MAIN(int argc, char *argv[]){ uhd::set_thread_priority_safe(); //variables to be set by po std::string args, file, ant, subdev, ref; size_t total_num_samps; double rate, freq, gain, bw; std::string addr, port; //setup the program options po::options_description desc("Allowed options"); desc.add_options() ("help", "help message") ("args", po::value<std::string>(&args)->default_value(""), "multi uhd device address args") ("nsamps", po::value<size_t>(&total_num_samps)->default_value(1000), "total number of samples to receive") ("rate", po::value<double>(&rate)->default_value(100e6/16), "rate of incoming samples") ("freq", po::value<double>(&freq)->default_value(0), "rf center frequency in Hz") ("gain", po::value<double>(&gain)->default_value(0), "gain for the RF chain") ("ant", po::value<std::string>(&ant), "antenna selection") ("subdev", po::value<std::string>(&subdev), "subdevice specification") ("bw", po::value<double>(&bw), "analog frontend filter bandwidth in Hz") ("port", po::value<std::string>(&port)->default_value("7124"), "server udp port") ("addr", po::value<std::string>(&addr)->default_value("192.168.1.10"), "resolvable server address") ("ref", po::value<std::string>(&ref)->default_value("internal"), "reference source (internal, external, mimo)") ("int-n", "tune USRP with integer-N tuning") ; po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); //print the help message if (vm.count("help")){ std::cout << boost::format("UHD RX to UDP %s") % desc << std::endl; return ~0; } //create a usrp device std::cout << std::endl; std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args); std::cout << boost::format("Using Device: %s") % usrp->get_pp_string() << std::endl; //Lock mboard clocks usrp->set_clock_source(ref); //set the rx sample rate std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate/1e6) << std::endl; usrp->set_rx_rate(rate); std::cout << boost::format("Actual RX Rate: %f Msps...") % (usrp->get_rx_rate()/1e6) << std::endl << std::endl; //set the rx center frequency std::cout << boost::format("Setting RX Freq: %f MHz...") % (freq/1e6) << std::endl; uhd::tune_request_t tune_request(freq); if(vm.count("int-n")) tune_request.args = uhd::device_addr_t("mode_n=integer"); usrp->set_rx_freq(tune_request); std::cout << boost::format("Actual RX Freq: %f MHz...") % (usrp->get_rx_freq()/1e6) << std::endl << std::endl; //set the rx rf gain std::cout << boost::format("Setting RX Gain: %f dB...") % gain << std::endl; usrp->set_rx_gain(gain); std::cout << boost::format("Actual RX Gain: %f dB...") % usrp->get_rx_gain() << std::endl << std::endl; //set the analog frontend filter bandwidth if (vm.count("bw")){ std::cout << boost::format("Setting RX Bandwidth: %f MHz...") % (bw/1e6) << std::endl; usrp->set_rx_bandwidth(bw); std::cout << boost::format("Actual RX Bandwidth: %f MHz...") % (usrp->get_rx_bandwidth()/1e6) << std::endl << std::endl; } //set the antenna if (vm.count("ant")) usrp->set_rx_antenna(ant); boost::this_thread::sleep(boost::posix_time::seconds(1)); //allow for some setup time //Check Ref and LO Lock detect std::vector<std::string> sensor_names; sensor_names = usrp->get_rx_sensor_names(0); if (std::find(sensor_names.begin(), sensor_names.end(), "lo_locked") != sensor_names.end()) { uhd::sensor_value_t lo_locked = usrp->get_rx_sensor("lo_locked",0); std::cout << boost::format("Checking RX: %s ...") % lo_locked.to_pp_string() << std::endl; UHD_ASSERT_THROW(lo_locked.to_bool()); } sensor_names = usrp->get_mboard_sensor_names(0); if ((ref == "mimo") and (std::find(sensor_names.begin(), sensor_names.end(), "mimo_locked") != sensor_names.end())) { uhd::sensor_value_t mimo_locked = usrp->get_mboard_sensor("mimo_locked",0); std::cout << boost::format("Checking RX: %s ...") % mimo_locked.to_pp_string() << std::endl; UHD_ASSERT_THROW(mimo_locked.to_bool()); } if ((ref == "external") and (std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end())) { uhd::sensor_value_t ref_locked = usrp->get_mboard_sensor("ref_locked",0); std::cout << boost::format("Checking RX: %s ...") % ref_locked.to_pp_string() << std::endl; UHD_ASSERT_THROW(ref_locked.to_bool()); } //create a receive streamer uhd::stream_args_t stream_args("fc32"); //complex floats uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args); //setup streaming uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); stream_cmd.num_samps = total_num_samps; stream_cmd.stream_now = true; rx_stream->issue_stream_cmd(stream_cmd); //loop until total number of samples reached size_t num_acc_samps = 0; //number of accumulated samples uhd::rx_metadata_t md; std::vector<std::complex<float> > buff(rx_stream->get_max_num_samps()); uhd::transport::udp_simple::sptr udp_xport = uhd::transport::udp_simple::make_connected(addr, port); while(num_acc_samps < total_num_samps){ size_t num_rx_samps = rx_stream->recv( &buff.front(), buff.size(), md ); //handle the error codes switch(md.error_code){ case uhd::rx_metadata_t::ERROR_CODE_NONE: break; case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: if (num_acc_samps == 0) continue; std::cout << boost::format( "Got timeout before all samples received, possible packet loss, exiting loop..." ) << std::endl; goto done_loop; default: std::cout << boost::format( "Got error code 0x%x, exiting loop..." ) % md.error_code << std::endl; goto done_loop; } //send complex single precision floating point samples over udp udp_xport->send(boost::asio::buffer(buff, num_rx_samps*sizeof(buff.front()))); num_acc_samps += num_rx_samps; } done_loop: //finished std::cout << std::endl << "Done!" << std::endl << std::endl; return EXIT_SUCCESS; }