From 178ac3f1c9950d383c8f64b3df464c0f943c4a23 Mon Sep 17 00:00:00 2001 From: Ben Hilburn Date: Tue, 4 Feb 2014 11:04:07 -0800 Subject: Merging USRP X300 and X310 support!! --- host/examples/CMakeLists.txt | 1 + host/examples/benchmark_rate.cpp | 24 ++- host/examples/fpgpio.cpp | 374 +++++++++++++++++++++++++++++++++ host/examples/rx_timed_samples.cpp | 26 ++- host/examples/transport_hammer.cpp | 3 +- host/examples/tx_samples_from_file.cpp | 7 +- host/examples/tx_timed_samples.cpp | 4 +- 7 files changed, 427 insertions(+), 12 deletions(-) create mode 100644 host/examples/fpgpio.cpp (limited to 'host/examples') diff --git a/host/examples/CMakeLists.txt b/host/examples/CMakeLists.txt index 53e913070..4f394bbef 100644 --- a/host/examples/CMakeLists.txt +++ b/host/examples/CMakeLists.txt @@ -36,6 +36,7 @@ SET(example_sources tx_waveforms.cpp txrx_loopback_to_file.cpp latency_test.cpp + fpgpio.cpp ) #for each source: build an executable and install diff --git a/host/examples/benchmark_rate.cpp b/host/examples/benchmark_rate.cpp index 3b2ab8a1f..ea49d48d9 100644 --- a/host/examples/benchmark_rate.cpp +++ b/host/examples/benchmark_rate.cpp @@ -66,8 +66,18 @@ void benchmark_rx_rate(uhd::usrp::multi_usrp::sptr usrp, const std::string &rx_c cmd.time_spec = usrp->get_time_now() + uhd::time_spec_t(0.05); cmd.stream_now = (buffs.size() == 1); rx_stream->issue_stream_cmd(cmd); + while (not boost::this_thread::interruption_requested()){ - num_rx_samps += rx_stream->recv(buffs, max_samps_per_packet, md)*rx_stream->get_num_channels(); + try { + num_rx_samps += rx_stream->recv(buffs, max_samps_per_packet, md)*rx_stream->get_num_channels(); + } + catch (...) { + /* apparently, the boost thread interruption can sometimes result in + throwing exceptions not of type boost::exception, this catch allows + this thread to still attempt to issue the STREAM_MODE_STOP_CONTINUOUS + */ + break; + } //handle the error codes switch(md.error_code){ @@ -78,10 +88,13 @@ void benchmark_rx_rate(uhd::usrp::multi_usrp::sptr usrp, const std::string &rx_c } break; + // ERROR_CODE_OVERFLOW can indicate overflow or sequence error case uhd::rx_metadata_t::ERROR_CODE_OVERFLOW: - had_an_overflow = true; last_time = md.time_spec; - num_overflows++; + had_an_overflow = true; + // check out_of_sequence flag to see if it was a sequence error or overflow + if (!md.out_of_sequence) + num_overflows++; break; default: @@ -89,7 +102,6 @@ void benchmark_rx_rate(uhd::usrp::multi_usrp::sptr usrp, const std::string &rx_c std::cerr << "Unexpected error on recv, continuing..." << std::endl; break; } - } rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); } @@ -226,7 +238,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ 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(channel_strings[ch]); - if(chan >= usrp->get_tx_num_channels() or chan >= usrp->get_tx_num_channels()){ + if(chan >= usrp->get_tx_num_channels() or chan >= usrp->get_rx_num_channels()){ throw std::runtime_error("Invalid channel(s) specified."); } else channel_nums.push_back(boost::lexical_cast(channel_strings[ch])); @@ -275,6 +287,6 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //finished std::cout << std::endl << "Done!" << std::endl << std::endl; - + return EXIT_SUCCESS; } diff --git a/host/examples/fpgpio.cpp b/host/examples/fpgpio.cpp new file mode 100644 index 000000000..89a6ecec3 --- /dev/null +++ b/host/examples/fpgpio.cpp @@ -0,0 +1,374 @@ +// +// Copyright 2014 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +// Example for front panel GPIO. +// Bits are set as follows: +// FPGPIO[0] = ATR output 1 at idle +// FPGPIO[1] = ATR output 1 during RX +// FPGPIO[2] = ATR output 1 during TX +// FPGPIO[3] = ATR output 1 during full duplex +// FPGPIO[4] = output +// FPGPIO[5] = input +// FPGPIO[6] = input +// FPGPIO[7] = input +// FPGPIO[8] = input +// FPGPIO[9] = input +// FPGPIO[10] = input +// The example cycles through idle, TX, RX, and full duplex, spending 2 seconds for each. +// Outputs can be physically looped back to inputs for verification testing. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FPGPIO_DEFAULT_CPU_FORMAT "fc32" +#define FPGPIO_DEFAULT_OTW_FORMAT "sc16" +#define FPGPIO_DEFAULT_RX_RATE 1e6 +#define FPGPIO_DEFAULT_TX_RATE 1e6 +#define FPGPIO_DEFAULT_DWELL_TIME 2.0 +#define FPGPIO_NUM_BITS 11 +#define FPGPIO_BIT(x) (1 << x) + +namespace po = boost::program_options; + +static bool stop_signal_called = false; +void sig_int_handler(int){stop_signal_called = true;} + +std::string to_bit_string(boost::uint16_t val) +{ + std::string out; + for (int i = FPGPIO_NUM_BITS - 1; i >= 0; i--) + { + std::string bit = ((val >> i) & 1) ? "1" : "0"; + out += " "; + out += bit; + } + return out; +} + +void output_reg_values(const std::string bank, const uhd::usrp::multi_usrp::sptr &usrp) +{ + std::cout << (boost::format("Bit ")); + for (int i = FPGPIO_NUM_BITS - 1; i >= 0; i--) + std::cout << (boost::format(" %s%d") % (i < 10 ? " " : "") % i); + std::cout << std::endl; + std::cout << "CTRL: " << to_bit_string(uint16_t(usrp->get_gpio_attr(bank, std::string("CTRL")))) << std::endl; + std::cout << "DDR: " << to_bit_string(uint16_t(usrp->get_gpio_attr(bank, std::string("DDR")))) << std::endl; + std::cout << "ATR_0X: " << to_bit_string(uint16_t(usrp->get_gpio_attr(bank, std::string("ATR_0X")))) << std::endl; + std::cout << "ATR_RX: " << to_bit_string(uint16_t(usrp->get_gpio_attr(bank, std::string("ATR_RX")))) << std::endl; + std::cout << "ATR_TX: " << to_bit_string(uint16_t(usrp->get_gpio_attr(bank, std::string("ATR_TX")))) << std::endl; + std::cout << "ATR_XX: " << to_bit_string(uint16_t(usrp->get_gpio_attr(bank, std::string("ATR_XX")))) << std::endl; + std::cout << "OUT: " << to_bit_string(uint16_t(usrp->get_gpio_attr(bank, std::string("OUT")))) << std::endl; + std::cout << "READBACK: " << to_bit_string(uint16_t(usrp->get_gpio_attr(bank, std::string("READBACK")))) << std::endl; +} + +int UHD_SAFE_MAIN(int argc, char *argv[]){ + uhd::set_thread_priority_safe(); + + //variables to be set by po + std::string args; + std::string cpu, otw; + double rx_rate, tx_rate, dwell; + const std::string fpgpio = "FP0"; + + //setup the program options + po::options_description desc("Allowed options"); + desc.add_options() + ("help", "help message") + ("args", po::value(&args)->default_value(""), "multi uhd device address args") + ("repeat", "repeat loop until Ctrl-C is pressed") + ("cpu", po::value(&cpu)->default_value(FPGPIO_DEFAULT_CPU_FORMAT), "cpu data format") + ("otw", po::value(&otw)->default_value(FPGPIO_DEFAULT_OTW_FORMAT), "over the wire data format") + ("rx_rate", po::value(&rx_rate)->default_value(FPGPIO_DEFAULT_RX_RATE), "rx sample rate") + ("tx_rate", po::value(&tx_rate)->default_value(FPGPIO_DEFAULT_TX_RATE), "tx sample rate") + ("dwell", po::value(&dwell)->default_value(FPGPIO_DEFAULT_DWELL_TIME), "dwell time in seconds for each test case") + ; + 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("Front Panel GPIO %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; + + //print out initial unconfigured state of FP GPIO + std::cout << "Unconfigured GPIO values:" << std::endl; + output_reg_values(fpgpio, usrp); + + //configure GPIO registers + uint32_t ctrl = 0; // default all as manual + uint32_t ddr = 0; // default all as input + uint32_t atr_idle = 0; + uint32_t atr_rx = 0; + uint32_t atr_tx = 0; + uint32_t atr_duplex = 0; + uint32_t mask = 0x7ff; + + //set up FPGPIO outputs: + //FPGPIO[0] = ATR output 1 at idle + ctrl |= FPGPIO_BIT(0); + atr_idle |= FPGPIO_BIT(0); + ddr |= FPGPIO_BIT(0); + + //FPGPIO[1] = ATR output 1 during RX + ctrl |= FPGPIO_BIT(1); + ddr |= FPGPIO_BIT(1); + atr_rx |= FPGPIO_BIT(1); + + //FPGPIO[2] = ATR output 1 during TX + ctrl |= FPGPIO_BIT(2); + ddr |= FPGPIO_BIT(2); + atr_tx |= FPGPIO_BIT(2); + + //FPGPIO[3] = ATR output 1 during full duplex + ctrl |= FPGPIO_BIT(3); + ddr |= FPGPIO_BIT(3); + atr_duplex |= FPGPIO_BIT(3); + + //FPGPIO[4] = output + ddr |= FPGPIO_BIT(4); + + //set data direction register (DDR) + usrp->set_gpio_attr(fpgpio, std::string("DDR"), ddr, mask); + + //set ATR registers + usrp->set_gpio_attr(fpgpio, std::string("ATR_0X"), atr_idle, mask); + usrp->set_gpio_attr(fpgpio, std::string("ATR_RX"), atr_rx, mask); + usrp->set_gpio_attr(fpgpio, std::string("ATR_TX"), atr_tx, mask); + usrp->set_gpio_attr(fpgpio, std::string("ATR_XX"), atr_duplex, mask); + + //set control register + usrp->set_gpio_attr(fpgpio, std::string("CTRL"), ctrl, mask); + + //print out initial state of FP GPIO + std::cout << "\nConfigured GPIO values:" << std::endl; + output_reg_values(fpgpio, usrp); + std::cout << std::endl; + + //set up streams + uhd::stream_args_t rx_args(cpu, otw); + uhd::stream_args_t tx_args(cpu, otw); + uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(rx_args); + uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(tx_args); + uhd::stream_cmd_t rx_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); + rx_cmd.stream_now = true; + usrp->set_rx_rate(rx_rate); + usrp->set_tx_rate(tx_rate); + + //set up buffers for tx and rx + const size_t max_samps_per_packet = rx_stream->get_max_num_samps(); + const size_t nsamps_per_buff = max_samps_per_packet; + std::vector rx_buff(max_samps_per_packet*uhd::convert::get_bytes_per_item(cpu)); + std::vector tx_buff(max_samps_per_packet*uhd::convert::get_bytes_per_item(cpu)); + std::vector rx_buffs, tx_buffs; + for (size_t ch = 0; ch < rx_stream->get_num_channels(); ch++) + rx_buffs.push_back(&rx_buff.front()); //same buffer for each channel + for (size_t ch = 0; ch < tx_stream->get_num_channels(); ch++) + tx_buffs.push_back(&tx_buff.front()); //same buffer for each channel + + uhd::rx_metadata_t rx_md; + uhd::tx_metadata_t tx_md; + tx_md.has_time_spec = false; + tx_md.start_of_burst = true; + uhd::time_spec_t stop_time; + double timeout = 0.01; + uhd::time_spec_t dwell_time(dwell); + int loop = 0; + boost::uint32_t rb, expected; + + //register singal handler + std::signal(SIGINT, &sig_int_handler); + + //Test the mask - only need to test once with no dwell time + std::cout << "\nTesting mask..." << std::flush; + //send a value of all 1's to the DDR with a mask for only bit 10 + usrp->set_gpio_attr(fpgpio, std::string("DDR"), ~0, FPGPIO_BIT(10)); + //bit 10 should now be 1, but all the other bits should be unchanged + rb = usrp->get_gpio_attr(fpgpio, std::string("DDR")) & mask; + expected = ddr | FPGPIO_BIT(10); + if (rb == expected) + std::cout << "pass" << std::endl; + else + std::cout << "fail" << std::endl; + std::cout << std::endl; + output_reg_values(fpgpio, usrp); + usrp->set_gpio_attr(fpgpio, std::string("DDR"), ddr, mask); + + while (not stop_signal_called) + { + int failures = 0; + + if (vm.count("repeat")) + std::cout << "Press Ctrl + C to quit..." << std::endl; + + // test user controlled GPIO and ATR idle by setting bit 4 high for 1 second + std::cout << "\nTesting user controlled GPIO and ATR idle output..." << std::flush; + usrp->set_gpio_attr(fpgpio, "OUT", 1 << 4, 1 << 4); + stop_time = usrp->get_time_now() + dwell_time; + while (not stop_signal_called and usrp->get_time_now() < stop_time) + { + boost::this_thread::sleep(boost::posix_time::milliseconds(100)); + } + rb = usrp->get_gpio_attr(fpgpio, "READBACK"); + expected = FPGPIO_BIT(4) | FPGPIO_BIT(0); + if ((rb & expected) != expected) + { + ++failures; + std::cout << "fail" << std::endl; + if ((rb & FPGPIO_BIT(0)) == 0) + std::cout << "Bit 0 should be set, but is not" << std::endl; + if ((rb & FPGPIO_BIT(4)) == 0) + std::cout << "Bit 4 should be set, but is not" << std::endl; + } else { + std::cout << "pass" << std::endl; + } + std::cout << std::endl; + output_reg_values(fpgpio, usrp); + usrp->set_gpio_attr(fpgpio, "OUT", 0, FPGPIO_BIT(4)); + if (stop_signal_called) + break; + + // test ATR RX by receiving for 1 second + std::cout << "\nTesting ATR RX output..." << std::flush; + rx_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS; + rx_stream->issue_stream_cmd(rx_cmd); + stop_time = usrp->get_time_now() + dwell_time; + while (not stop_signal_called and usrp->get_time_now() < stop_time) + { + try { + rx_stream->recv(rx_buffs, nsamps_per_buff, rx_md, timeout); + } catch(...){} + } + rb = usrp->get_gpio_attr(fpgpio, "READBACK"); + expected = FPGPIO_BIT(1); + if ((rb & expected) != expected) + { + ++failures; + std::cout << "fail" << std::endl; + std::cout << "Bit 1 should be set, but is not" << std::endl; + } else { + std::cout << "pass" << std::endl; + } + std::cout << std::endl; + output_reg_values(fpgpio, usrp); + rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); + //clear out any data left in the rx stream + try { + rx_stream->recv(rx_buffs, nsamps_per_buff, rx_md, timeout); + } catch(...){} + if (stop_signal_called) + break; + + // test ATR TX by transmitting for 1 second + std::cout << "\nTesting ATR TX output..." << std::flush; + stop_time = usrp->get_time_now() + dwell_time; + tx_md.start_of_burst = true; + tx_md.end_of_burst = false; + while (not stop_signal_called and usrp->get_time_now() < stop_time) + { + try { + tx_stream->send(tx_buffs, nsamps_per_buff, tx_md, timeout); + tx_md.start_of_burst = false; + } catch(...){} + } + rb = usrp->get_gpio_attr(fpgpio, "READBACK"); + expected = FPGPIO_BIT(2); + if ((rb & expected) != expected) + { + ++failures; + std::cout << "fail" << std::endl; + std::cout << "Bit 2 should be set, but is not" << std::endl; + } else { + std::cout << "pass" << std::endl; + } + std::cout << std::endl; + output_reg_values(fpgpio, usrp); + tx_md.end_of_burst = true; + try { + tx_stream->send(tx_buffs, nsamps_per_buff, tx_md, timeout); + } catch(...){} + if (stop_signal_called) + break; + + // test ATR RX by transmitting and receiving for 1 second + std::cout << "\nTesting ATR full duplex output..." << std::flush; + rx_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS; + rx_stream->issue_stream_cmd(rx_cmd); + tx_md.start_of_burst = true; + tx_md.end_of_burst = false; + stop_time = usrp->get_time_now() + dwell_time; + while (not stop_signal_called and usrp->get_time_now() < stop_time) + { + try { + tx_stream->send(rx_buffs, nsamps_per_buff, tx_md, timeout); + tx_md.start_of_burst = false; + rx_stream->recv(tx_buffs, nsamps_per_buff, rx_md, timeout); + } catch(...){} + } + rb = usrp->get_gpio_attr(fpgpio, "READBACK"); + expected = FPGPIO_BIT(3); + if ((rb & expected) != expected) + { + ++failures; + std::cout << "fail" << std::endl; + std::cout << "Bit 3 should be set, but is not" << std::endl; + } else { + std::cout << "pass" << std::endl; + } + std::cout << std::endl; + output_reg_values(fpgpio, usrp); + rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); + tx_md.end_of_burst = true; + try { + tx_stream->send(tx_buffs, nsamps_per_buff, tx_md, timeout); + } catch(...){} + //clear out any data left in the rx stream + try { + rx_stream->recv(rx_buffs, nsamps_per_buff, rx_md, timeout); + } catch(...){} + + std::cout << std::endl; + if (failures) + std::cout << failures << " tests failed" << std::endl; + else + std::cout << "All tests passed!" << std::endl; + + if (!vm.count("repeat")) + break; + + std::cout << (boost::format("\nLoop %d completed") % ++loop) << std::endl; + } + + //finished + std::cout << std::endl << "Done!" << std::endl << std::endl; + + return EXIT_SUCCESS; +} diff --git a/host/examples/rx_timed_samples.cpp b/host/examples/rx_timed_samples.cpp index 0eea2ffee..cc9216cb7 100644 --- a/host/examples/rx_timed_samples.cpp +++ b/host/examples/rx_timed_samples.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -30,19 +31,24 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //variables to be set by po std::string args; + std::string wire; double seconds_in_future; size_t total_num_samps; double rate; + std::string channel_list; //setup the program options po::options_description desc("Allowed options"); desc.add_options() ("help", "help message") ("args", po::value(&args)->default_value(""), "single uhd device address args") + ("wire", po::value(&wire)->default_value(""), "the over the wire type, sc16, sc8, etc") ("secs", po::value(&seconds_in_future)->default_value(1.5), "number of seconds in the future to receive") ("nsamps", po::value(&total_num_samps)->default_value(10000), "total number of samples to receive") ("rate", po::value(&rate)->default_value(100e6/16), "rate of incoming samples") ("dilv", "specify to disable inner-loop verbose") + ("channels", po::value(&channel_list)->default_value("0"), "which channel(s) to use (specify \"0\", \"1\", \"0,1\", etc)") + ; po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); @@ -62,6 +68,18 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ 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; + //detect which channels to use + std::vector channel_strings; + std::vector 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(channel_strings[ch]); + if(chan >= usrp->get_tx_num_channels() or chan >= usrp->get_rx_num_channels()){ + throw std::runtime_error("Invalid channel(s) specified."); + } + else channel_nums.push_back(boost::lexical_cast(channel_strings[ch])); + } + //set the rx sample rate std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate/1e6) << std::endl; usrp->set_rx_rate(rate); @@ -71,7 +89,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ usrp->set_time_now(uhd::time_spec_t(0.0)); //create a receive streamer - uhd::stream_args_t stream_args("fc32"); //complex floats + uhd::stream_args_t stream_args("fc32", wire); //complex floats + stream_args.channels = channel_nums; uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args); //setup streaming @@ -90,6 +109,9 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //allocate buffer to receive with samples std::vector > buff(rx_stream->get_max_num_samps()); + std::vector buffs; + for (size_t ch = 0; ch < rx_stream->get_num_channels(); ch++) + buffs.push_back(&buff.front()); //same buffer for each channel //the first call to recv() will block this many seconds before receiving double timeout = seconds_in_future + 0.1; //timeout (delay before receive + padding) @@ -98,7 +120,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ while(num_acc_samps < total_num_samps){ //receive a single packet size_t num_rx_samps = rx_stream->recv( - &buff.front(), buff.size(), md, timeout, true + buffs, buff.size(), md, timeout, true ); //use a small timeout for subsequent packets diff --git a/host/examples/transport_hammer.cpp b/host/examples/transport_hammer.cpp index a44e81a82..4b949e5bd 100644 --- a/host/examples/transport_hammer.cpp +++ b/host/examples/transport_hammer.cpp @@ -83,7 +83,8 @@ void rx_hammer(uhd::usrp::multi_usrp::sptr usrp, const std::string &rx_cpu, uhd: case uhd::rx_metadata_t::ERROR_CODE_OVERFLOW: had_an_overflow = true; last_time = md.time_spec; - num_overflows++; + if (!md.out_of_sequence) + num_overflows++; break; default: diff --git a/host/examples/tx_samples_from_file.cpp b/host/examples/tx_samples_from_file.cpp index 6926f8690..000f5086b 100644 --- a/host/examples/tx_samples_from_file.cpp +++ b/host/examples/tx_samples_from_file.cpp @@ -71,7 +71,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //variables to be set by po std::string args, file, type, ant, subdev, ref, wirefmt; size_t spb; - double rate, freq, gain, bw, delay; + double rate, freq, gain, bw, delay, lo_off; //setup the program options po::options_description desc("Allowed options"); @@ -83,6 +83,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ ("spb", po::value(&spb)->default_value(10000), "samples per buffer") ("rate", po::value(&rate), "rate of outgoing samples") ("freq", po::value(&freq), "RF center frequency in Hz") + ("lo_off", po::value(&lo_off), "Offset for frontend LO in Hz (optional)") ("gain", po::value(&gain), "gain for the RF chain") ("ant", po::value(&ant), "daughterboard antenna selection") ("subdev", po::value(&subdev), "daughterboard subdevice specification") @@ -133,7 +134,9 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ return ~0; } std::cout << boost::format("Setting TX Freq: %f MHz...") % (freq/1e6) << std::endl; - uhd::tune_request_t tune_request(freq); + uhd::tune_request_t tune_request; + if(vm.count("lo_off")) tune_request = uhd::tune_request_t(freq, lo_off); + else tune_request = uhd::tune_request_t(freq); if(vm.count("int-n")) tune_request.args = uhd::device_addr_t("mode_n=int-n"); usrp->set_tx_freq(tune_request); std::cout << boost::format("Actual TX Freq: %f MHz...") % (usrp->get_tx_freq()/1e6) << std::endl << std::endl; diff --git a/host/examples/tx_timed_samples.cpp b/host/examples/tx_timed_samples.cpp index 8826deadd..667ae66a9 100644 --- a/host/examples/tx_timed_samples.cpp +++ b/host/examples/tx_timed_samples.cpp @@ -31,6 +31,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //variables to be set by po std::string args; + std::string wire; double seconds_in_future; size_t total_num_samps; double rate; @@ -41,6 +42,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ desc.add_options() ("help", "help message") ("args", po::value(&args)->default_value(""), "single uhd device address args") + ("wire", po::value(&wire)->default_value(""), "the over the wire type, sc16, sc8, etc") ("secs", po::value(&seconds_in_future)->default_value(1.5), "number of seconds in the future to transmit") ("nsamps", po::value(&total_num_samps)->default_value(10000), "total number of samples to transmit") ("rate", po::value(&rate)->default_value(100e6/16), "rate of outgoing samples") @@ -74,7 +76,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ usrp->set_time_now(uhd::time_spec_t(0.0)); //create a transmit streamer - uhd::stream_args_t stream_args("fc32"); //complex floats + uhd::stream_args_t stream_args("fc32", wire); //complex floats uhd::tx_streamer::sptr tx_stream = usrp->get_tx_stream(stream_args); //allocate buffer with data to send -- cgit v1.2.3