aboutsummaryrefslogtreecommitdiffstats
path: root/host/examples
diff options
context:
space:
mode:
authorBen Hilburn <ben.hilburn@ettus.com>2014-02-04 11:04:07 -0800
committerBen Hilburn <ben.hilburn@ettus.com>2014-02-04 11:04:07 -0800
commit178ac3f1c9950d383c8f64b3df464c0f943c4a23 (patch)
tree318ed621a7b59b7d34d4ce6e4a92f73f0bcef509 /host/examples
parent2718ac110fa931cc29daf7cb3dc5ab6230ee02ab (diff)
downloaduhd-178ac3f1c9950d383c8f64b3df464c0f943c4a23.tar.gz
uhd-178ac3f1c9950d383c8f64b3df464c0f943c4a23.tar.bz2
uhd-178ac3f1c9950d383c8f64b3df464c0f943c4a23.zip
Merging USRP X300 and X310 support!!
Diffstat (limited to 'host/examples')
-rw-r--r--host/examples/CMakeLists.txt1
-rw-r--r--host/examples/benchmark_rate.cpp24
-rw-r--r--host/examples/fpgpio.cpp374
-rw-r--r--host/examples/rx_timed_samples.cpp26
-rw-r--r--host/examples/transport_hammer.cpp3
-rw-r--r--host/examples/tx_samples_from_file.cpp7
-rw-r--r--host/examples/tx_timed_samples.cpp4
7 files changed, 427 insertions, 12 deletions
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<int>(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<int>(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 <http://www.gnu.org/licenses/>.
+//
+
+// 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 <uhd/utils/thread_priority.hpp>
+#include <uhd/utils/safe_main.hpp>
+#include <uhd/usrp/multi_usrp.hpp>
+#include <uhd/convert.hpp>
+#include <boost/program_options.hpp>
+#include <boost/format.hpp>
+#include <boost/thread.hpp>
+#include <csignal>
+#include <iostream>
+
+#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<std::string>(&args)->default_value(""), "multi uhd device address args")
+ ("repeat", "repeat loop until Ctrl-C is pressed")
+ ("cpu", po::value<std::string>(&cpu)->default_value(FPGPIO_DEFAULT_CPU_FORMAT), "cpu data format")
+ ("otw", po::value<std::string>(&otw)->default_value(FPGPIO_DEFAULT_OTW_FORMAT), "over the wire data format")
+ ("rx_rate", po::value<double>(&rx_rate)->default_value(FPGPIO_DEFAULT_RX_RATE), "rx sample rate")
+ ("tx_rate", po::value<double>(&tx_rate)->default_value(FPGPIO_DEFAULT_TX_RATE), "tx sample rate")
+ ("dwell", po::value<double>(&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<char> rx_buff(max_samps_per_packet*uhd::convert::get_bytes_per_item(cpu));
+ std::vector<char> tx_buff(max_samps_per_packet*uhd::convert::get_bytes_per_item(cpu));
+ std::vector<void *> 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 <uhd/usrp/multi_usrp.hpp>
#include <boost/program_options.hpp>
#include <boost/format.hpp>
+#include <boost/algorithm/string.hpp>
#include <iostream>
#include <complex>
@@ -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<std::string>(&args)->default_value(""), "single uhd device address args")
+ ("wire", po::value<std::string>(&wire)->default_value(""), "the over the wire type, sc16, sc8, etc")
("secs", po::value<double>(&seconds_in_future)->default_value(1.5), "number of seconds in the future to receive")
("nsamps", po::value<size_t>(&total_num_samps)->default_value(10000), "total number of samples to receive")
("rate", po::value<double>(&rate)->default_value(100e6/16), "rate of incoming samples")
("dilv", "specify to disable inner-loop verbose")
+ ("channels", po::value<std::string>(&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<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() or chan >= usrp->get_rx_num_channels()){
+ throw std::runtime_error("Invalid channel(s) specified.");
+ }
+ else channel_nums.push_back(boost::lexical_cast<int>(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<std::complex<float> > buff(rx_stream->get_max_num_samps());
+ std::vector<void *> 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<size_t>(&spb)->default_value(10000), "samples per buffer")
("rate", po::value<double>(&rate), "rate of outgoing samples")
("freq", po::value<double>(&freq), "RF center frequency in Hz")
+ ("lo_off", po::value<double>(&lo_off), "Offset for frontend LO in Hz (optional)")
("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")
@@ -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<std::string>(&args)->default_value(""), "single uhd device address args")
+ ("wire", po::value<std::string>(&wire)->default_value(""), "the over the wire type, sc16, sc8, etc")
("secs", po::value<double>(&seconds_in_future)->default_value(1.5), "number of seconds in the future to transmit")
("nsamps", po::value<size_t>(&total_num_samps)->default_value(10000), "total number of samples to transmit")
("rate", po::value<double>(&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