diff options
33 files changed, 395 insertions, 1231 deletions
| diff --git a/host/docs/coding.rst b/host/docs/coding.rst index 7533445ea..ecca4e8b8 100644 --- a/host/docs/coding.rst +++ b/host/docs/coding.rst @@ -23,40 +23,10 @@ The device API provides ways to:  See the documentation in *device.hpp* for reference.  ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -High-Level: The single usrp -^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The goal of the single usrp API is to wrap high level functions around the device properties. -The single usrp provides a fat interface to access the most common properties. -The single usrp provides ways to: - -* Set and get daughterboard gains. -* Set and get daughterboard antennas. -* Set and get the streaming rates. -* Tune the DSPs and daughterboards. -* Issue stream commands. -* Set the clock configuration. -* Set the usrp time registers. -* Get the underlying device (as discussed above). - -See the documentation in *usrp/single_usrp.hpp* for reference. - -^^^^^^^^^^^^^^^^^^^^^^^^^^^  High-Level: The multi usrp  ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The multi usrp API provides a wrapper around a device that represents several motherboards. -This API provides convenience calls just like the single usrp, -however the calls either work across all channels in the configuration, -or take a channel argument to specify which channel to configure. -The multi usrp provides ways to: - -* Set and get the sample rate across all channels. -* Issue a stream command across all channels. -* Set the time registers across all channels. -* Set and get individual daughterboard gains. -* Set and get individual daughterboard antennas. -* Tune individual DSPs and daughterboards. -* Get the underlying device (as discussed above). - +The Multi-USRP class provides a FAT interface to a single USRP with +one or more channels, or multiple USRPs in a homogeneous setup.  See the documentation in *usrp/multi_usrp.hpp* for reference.  ------------------------------------------------------------------------ diff --git a/host/docs/usrp2.rst b/host/docs/usrp2.rst index 2ee49646f..70101bd87 100644 --- a/host/docs/usrp2.rst +++ b/host/docs/usrp2.rst @@ -81,7 +81,7 @@ The safe-mode button is a pushbutton switch (S2) located inside the enclosure.  To boot into the safe image, hold-down the safe-mode button while power-cycling the device.  Continue to hold-down the button until the front-panel LEDs blink and remain solid. -When in safe-mode, the USRP-N Series will always have the IP address 192.168.10.2 +When in safe-mode, the USRP-N device will always have the IP address 192.168.10.2  ------------------------------------------------------------------------  Setup networking @@ -154,31 +154,53 @@ Run the following commands:      cd <prefix>/share/uhd/utils      sudo ./usrp2_recovery.py --ifc=eth0 --new-ip=192.168.10.3 +------------------------------------------------------------------------ +Communication problems +------------------------------------------------------------------------ +When setting up a development machine for the first time, +you may have various difficulties communicating with the USRP device. +The following tips are designed to help narrow-down and diagnose the problem. +  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Debugging networking problems +Firewall issues  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -**Disable the firewall:** -If uhd_find_devices gives you nothing -but uhd_find_devices --args addr=192.168.10.2 yeilds a discovered device, +When the IP address is not specified, +the device discovery sends broadcast UDP packets from each ethernet interface. +Many firewalls will block the replies to these broadcast packets. +If disabling your system's firewall, +or specifying the IP address yeilds a discovered device,  then your firewall may be blocking replies to UDP broadcast packets. +If this is the case, we recommend that you disable the firewall, +or create a rule to allow all incoming packets with UDP source port 49152. + +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Ping the device +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The USRP will reply to icmp echo requests. +A successful ping response means that the device has booted properly, +and that it is using the expected IP address. -**Ping the USRP2:** -The USRP2 will reply to icmp echo requests.  ::      ping 192.168.10.2 -**Monitor the serial output:** +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Monitor the serial output +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  Read the serial port to get debug verbose from the embedded microcontroller. -Use a standard USB to 3.3v-level serial converter at 230400 baud.  The microcontroller prints useful information about IP addresses, -MAC addresses, control packets, and fast-path settings. +MAC addresses, control packets, fast-path settings, and bootloading. +Use a standard USB to 3.3v-level serial converter at 230400 baud. +Connect GND to the converter ground, and connect TXD to the converter receive. +The RXD pin can be left unconnected as this is only a one-way communication.  * **USRP2:** Serial port located on the rear edge  * **N210:** Serial port located on the left side -**Monitor the host network traffic:** -Use wireshark to monitor packets sent to and received from the USRP2. +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Monitor the host network traffic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Use wireshark to monitor packets sent to and received from the device.  ------------------------------------------------------------------------  Addressing the device diff --git a/host/examples/benchmark_rx_rate.cpp b/host/examples/benchmark_rx_rate.cpp index c49d8bff0..118bf413c 100644 --- a/host/examples/benchmark_rx_rate.cpp +++ b/host/examples/benchmark_rx_rate.cpp @@ -1,5 +1,5 @@  // -// Copyright 2010 Ettus Research LLC +// Copyright 2010-2011 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 @@ -17,7 +17,7 @@  #include <uhd/utils/thread_priority.hpp>  #include <uhd/utils/safe_main.hpp> -#include <uhd/usrp/single_usrp.hpp> +#include <uhd/usrp/multi_usrp.hpp>  #include <boost/math/special_functions/round.hpp>  #include <boost/program_options.hpp>  #include <boost/format.hpp> @@ -27,19 +27,19 @@  namespace po = boost::program_options;  static inline void test_device( -    uhd::usrp::single_usrp::sptr sdev, +    uhd::usrp::multi_usrp::sptr usrp,      double rx_rate_sps,      double duration_secs  ){ -    uhd::device::sptr dev = sdev->get_device(); +    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(dev->get_max_recv_samps_per_packet()); +    std::vector<std::complex<float> > buff(max_samps_per_packet);      //flush the buffers in the recv path -    while(dev->recv( +    while(usrp->get_device()->recv(          &buff.front(), buff.size(), md,          uhd::io_type_t::COMPLEX_FLOAT32,          uhd::device::RECV_MODE_ONE_PACKET @@ -55,9 +55,9 @@ static inline void test_device(      uhd::time_spec_t initial_time_spec;      uhd::time_spec_t next_expected_time_spec; -    sdev->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); +    usrp->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);      do { -        size_t num_rx_samps = dev->recv( +        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 @@ -89,18 +89,19 @@ static inline void test_device(              got_first_packet = true;          } -        total_lost_samples += boost::math::iround(rx_rate_sps*(md.time_spec - next_expected_time_spec).get_real_secs()); +        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)); -    sdev->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); +    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)/dev->get_max_recv_samps_per_packet()); +    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; @@ -136,22 +137,22 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      //create a usrp device      std::cout << std::endl;      std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; -    uhd::usrp::single_usrp::sptr sdev = uhd::usrp::single_usrp::make(args); -    std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << 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;      if (not vm.count("rate")){ -        sdev->set_rx_rate(500e3); //initial rate +        usrp->set_rx_rate(500e3); //initial rate          while(true){ -            double rate = sdev->get_rx_rate(); -            test_device(sdev, rate, duration); -            sdev->set_rx_rate(rate*2); //double the rate -            if (sdev->get_rx_rate() == rate) break; +            double rate = usrp->get_rx_rate(); +            test_device(usrp, rate, duration); +            usrp->set_rx_rate(rate*2); //double the rate +            if (usrp->get_rx_rate() == rate) break;          }      }      else{ -        sdev->set_rx_rate(only_rate); -        double rate = sdev->get_rx_rate(); -        test_device(sdev, rate, duration); +        usrp->set_rx_rate(only_rate); +        double rate = usrp->get_rx_rate(); +        test_device(usrp, rate, duration);      }      //finished diff --git a/host/examples/rx_ascii_art_dft.cpp b/host/examples/rx_ascii_art_dft.cpp index 260feca24..c407ecf91 100644 --- a/host/examples/rx_ascii_art_dft.cpp +++ b/host/examples/rx_ascii_art_dft.cpp @@ -17,10 +17,10 @@  #include <uhd/utils/thread_priority.hpp>  #include <uhd/utils/safe_main.hpp> -#include <uhd/usrp/single_usrp.hpp> +#include <uhd/usrp/multi_usrp.hpp>  #include "ascii_art_dft.hpp" //implementation  #include <boost/program_options.hpp> -#include <boost/thread.hpp> //gets time +#include <boost/thread/thread.hpp> //gets time  #include <boost/format.hpp>  #include <curses.h>  #include <iostream> @@ -41,7 +41,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      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") +        ("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)->default_value(0), "RF center frequency in Hz") @@ -65,23 +65,23 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      //create a usrp device      std::cout << std::endl;      std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; -    uhd::usrp::single_usrp::sptr sdev = uhd::usrp::single_usrp::make(args); -    std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << 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;      //set the rx sample rate      std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate/1e6) << std::endl; -    sdev->set_rx_rate(rate); -    std::cout << boost::format("Actual RX Rate: %f Msps...") % (sdev->get_rx_rate()/1e6) << std::endl << 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; -    sdev->set_rx_freq(freq); -    std::cout << boost::format("Actual RX Freq: %f Mhz...") % (sdev->get_rx_freq()/1e6) << std::endl << std::endl; +    usrp->set_rx_freq(freq); +    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; -    sdev->set_rx_gain(gain); -    std::cout << boost::format("Actual RX Gain: %f dB...") % sdev->get_rx_gain() << std::endl << std::endl; +    usrp->set_rx_gain(gain); +    std::cout << boost::format("Actual RX Gain: %f dB...") % usrp->get_rx_gain() << std::endl << std::endl;      //allocate recv buffer and metatdata      uhd::rx_metadata_t md; @@ -90,7 +90,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      //-- Initialize      //------------------------------------------------------------------      initscr(); //curses init -    sdev->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); +    usrp->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);      boost::system_time next_refresh = boost::get_system_time();      //------------------------------------------------------------------ @@ -98,7 +98,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      //------------------------------------------------------------------      while (true){          //read a buffer's worth of samples every iteration -        size_t num_rx_samps = sdev->get_device()->recv( +        size_t num_rx_samps = usrp->get_device()->recv(              &buff.front(), buff.size(), md,              uhd::io_type_t::COMPLEX_FLOAT32,              uhd::device::RECV_MODE_FULL_BUFF @@ -115,8 +115,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){          );          std::string frame = acsii_art_dft::dft_to_plot(              lpdft, COLS, LINES, -            sdev->get_rx_rate(), -            sdev->get_rx_freq(), +            usrp->get_rx_rate(), +            usrp->get_rx_freq(),              dyn_rng, ref_lvl          ); @@ -133,7 +133,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      //------------------------------------------------------------------      //-- Cleanup      //------------------------------------------------------------------ -    sdev->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); +    usrp->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS);      endwin(); //curses done      //finished diff --git a/host/examples/rx_samples_to_file.cpp b/host/examples/rx_samples_to_file.cpp index 81977035e..296f480b0 100644 --- a/host/examples/rx_samples_to_file.cpp +++ b/host/examples/rx_samples_to_file.cpp @@ -17,7 +17,7 @@  #include <uhd/utils/thread_priority.hpp>  #include <uhd/utils/safe_main.hpp> -#include <uhd/usrp/single_usrp.hpp> +#include <uhd/usrp/multi_usrp.hpp>  #include <boost/program_options.hpp>  #include <boost/format.hpp>  #include <boost/thread.hpp> @@ -39,7 +39,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      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") +        ("args", po::value<std::string>(&args)->default_value(""), "multi uhd device address args")          ("file", po::value<std::string>(&file)->default_value("out.16sc.dat"), "name of the file to write binary samples to")          ("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") @@ -52,49 +52,48 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      //print the help message      if (vm.count("help")){ -        std::cout << boost::format("UHD RX to File %s") % desc << std::endl; +        std::cout << boost::format("UHD RX samples to file %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::single_usrp::sptr sdev = uhd::usrp::single_usrp::make(args); -    uhd::device::sptr dev = sdev->get_device(); -    std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << 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;      //set the rx sample rate      std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate/1e6) << std::endl; -    sdev->set_rx_rate(rate); -    std::cout << boost::format("Actual RX Rate: %f Msps...") % (sdev->get_rx_rate()/1e6) << std::endl << 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; -    sdev->set_rx_freq(freq); -    std::cout << boost::format("Actual RX Freq: %f Mhz...") % (sdev->get_rx_freq()/1e6) << std::endl << std::endl; +    usrp->set_rx_freq(freq); +    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; -    sdev->set_rx_gain(gain); -    std::cout << boost::format("Actual RX Gain: %f dB...") % sdev->get_rx_gain() << std::endl << std::endl; +    usrp->set_rx_gain(gain); +    std::cout << boost::format("Actual RX Gain: %f dB...") % usrp->get_rx_gain() << std::endl << std::endl;      boost::this_thread::sleep(boost::posix_time::seconds(1)); //allow for some setup time -    std::cout << "LO Locked = " << sdev->get_rx_lo_locked() << std::endl; +    std::cout << "LO Locked = " << usrp->get_rx_lo_locked() << std::endl;      //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; -    sdev->issue_stream_cmd(stream_cmd); +    usrp->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<short> > buff(dev->get_max_recv_samps_per_packet()); +    std::vector<std::complex<short> > buff(usrp->get_device()->get_max_recv_samps_per_packet());      std::ofstream outfile(file.c_str(), std::ofstream::binary);      while(num_acc_samps < total_num_samps){ -        size_t num_rx_samps = dev->recv( +        size_t num_rx_samps = usrp->get_device()->recv(              &buff.front(), buff.size(), md,              uhd::io_type_t::COMPLEX_INT16,              uhd::device::RECV_MODE_ONE_PACKET diff --git a/host/examples/rx_samples_to_udp.cpp b/host/examples/rx_samples_to_udp.cpp index 55b9a50ba..801d8e361 100644 --- a/host/examples/rx_samples_to_udp.cpp +++ b/host/examples/rx_samples_to_udp.cpp @@ -17,7 +17,7 @@  #include <uhd/utils/thread_priority.hpp>  #include <uhd/utils/safe_main.hpp> -#include <uhd/usrp/single_usrp.hpp> +#include <uhd/usrp/multi_usrp.hpp>  #include <uhd/transport/udp_simple.hpp>  #include <boost/program_options.hpp>  #include <boost/format.hpp> @@ -40,7 +40,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      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") +        ("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") @@ -61,42 +61,41 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      //create a usrp device      std::cout << std::endl;      std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; -    uhd::usrp::single_usrp::sptr sdev = uhd::usrp::single_usrp::make(args); -    uhd::device::sptr dev = sdev->get_device(); -    std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << 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;      //set the rx sample rate      std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate/1e6) << std::endl; -    sdev->set_rx_rate(rate); -    std::cout << boost::format("Actual RX Rate: %f Msps...") % (sdev->get_rx_rate()/1e6) << std::endl << 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; -    sdev->set_rx_freq(freq); -    std::cout << boost::format("Actual RX Freq: %f Mhz...") % (sdev->get_rx_freq()/1e6) << std::endl << std::endl; +    usrp->set_rx_freq(freq); +    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; -    sdev->set_rx_gain(gain); -    std::cout << boost::format("Actual RX Gain: %f dB...") % sdev->get_rx_gain() << std::endl << std::endl; +    usrp->set_rx_gain(gain); +    std::cout << boost::format("Actual RX Gain: %f dB...") % usrp->get_rx_gain() << std::endl << std::endl;      boost::this_thread::sleep(boost::posix_time::seconds(1)); //allow for some setup time -    std::cout << "LO Locked = " << sdev->get_rx_lo_locked() << std::endl; +    std::cout << "LO Locked = " << usrp->get_rx_lo_locked() << std::endl;      //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; -    sdev->issue_stream_cmd(stream_cmd); +    usrp->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(dev->get_max_recv_samps_per_packet()); +    std::vector<std::complex<float> > buff(usrp->get_device()->get_max_recv_samps_per_packet());      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 = dev->recv( +        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 diff --git a/host/examples/rx_timed_samples.cpp b/host/examples/rx_timed_samples.cpp index a19532f50..9ebe36c5a 100644 --- a/host/examples/rx_timed_samples.cpp +++ b/host/examples/rx_timed_samples.cpp @@ -17,7 +17,7 @@  #include <uhd/utils/thread_priority.hpp>  #include <uhd/utils/safe_main.hpp> -#include <uhd/usrp/single_usrp.hpp> +#include <uhd/usrp/multi_usrp.hpp>  #include <boost/program_options.hpp>  #include <boost/format.hpp>  #include <iostream> @@ -60,22 +60,21 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      //create a usrp device      std::cout << std::endl;      std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; -    uhd::usrp::single_usrp::sptr sdev = uhd::usrp::single_usrp::make(args); -    uhd::device::sptr dev = sdev->get_device(); -    std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << 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;      //set the rx sample rate      std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate/1e6) << std::endl; -    sdev->set_rx_rate(rate); -    std::cout << boost::format("Actual RX Rate: %f Msps...") % (sdev->get_rx_rate()/1e6) << std::endl << 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; -    sdev->set_rx_freq(freq); -    std::cout << boost::format("Actual RX Freq: %f Mhz...") % (sdev->get_rx_freq()/1e6) << std::endl << std::endl; +    usrp->set_rx_freq(freq); +    std::cout << boost::format("Actual RX Freq: %f Mhz...") % (usrp->get_rx_freq()/1e6) << std::endl << std::endl;      std::cout << boost::format("Setting device timestamp to 0...") << std::endl; -    sdev->set_time_now(uhd::time_spec_t(0.0)); +    usrp->set_time_now(uhd::time_spec_t(0.0));      //setup streaming      std::cout << std::endl; @@ -86,14 +85,16 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      stream_cmd.num_samps = total_num_samps;      stream_cmd.stream_now = false;      stream_cmd.time_spec = uhd::time_spec_t(seconds_in_future); -    sdev->issue_stream_cmd(stream_cmd); +    usrp->issue_stream_cmd(stream_cmd); + +    //allocate buffer to receive +    std::vector<std::complex<float> > buff(usrp->get_device()->get_max_recv_samps_per_packet());      //loop until total number of samples reached      size_t num_acc_samps = 0; //number of accumulated samples      while(num_acc_samps < total_num_samps){          uhd::rx_metadata_t md; -        std::vector<std::complex<float> > buff(dev->get_max_recv_samps_per_packet()); -        size_t num_rx_samps = dev->recv( +        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 diff --git a/host/examples/test_async_messages.cpp b/host/examples/test_async_messages.cpp index b1d9d56d4..7f1094ee0 100644 --- a/host/examples/test_async_messages.cpp +++ b/host/examples/test_async_messages.cpp @@ -18,7 +18,7 @@  #include <uhd/utils/thread_priority.hpp>  #include <uhd/utils/safe_main.hpp>  #include <uhd/utils/static.hpp> -#include <uhd/usrp/single_usrp.hpp> +#include <uhd/usrp/multi_usrp.hpp>  #include <boost/assign/list_of.hpp>  #include <boost/program_options.hpp>  #include <boost/foreach.hpp> @@ -35,8 +35,7 @@ namespace po = boost::program_options;   *    Send a burst of many samples that will fragment internally.   *    We expect to get an burst ack async message.   */ -bool test_burst_ack_message(uhd::usrp::single_usrp::sptr sdev){ -    uhd::device::sptr dev = sdev->get_device(); +bool test_burst_ack_message(uhd::usrp::multi_usrp::sptr usrp){      std::cout << "Test burst ack message... " << std::flush;      uhd::tx_metadata_t md; @@ -45,16 +44,16 @@ bool test_burst_ack_message(uhd::usrp::single_usrp::sptr sdev){      md.has_time_spec  = false;      //3 times max-sps guarantees a SOB, no burst, and EOB packet -    std::vector<std::complex<float> > buff(dev->get_max_send_samps_per_packet()*3); +    std::vector<std::complex<float> > buff(usrp->get_device()->get_max_send_samps_per_packet()*3); -    dev->send( +    usrp->get_device()->send(          &buff.front(), buff.size(), md,          uhd::io_type_t::COMPLEX_FLOAT32,          uhd::device::SEND_MODE_FULL_BUFF      );      uhd::async_metadata_t async_md; -    if (not dev->recv_async_msg(async_md)){ +    if (not usrp->get_device()->recv_async_msg(async_md)){          std::cout << boost::format(              "failed:\n"              "    Async message recv timed out.\n" @@ -84,8 +83,7 @@ bool test_burst_ack_message(uhd::usrp::single_usrp::sptr sdev){   *    Send a start of burst packet with no following end of burst.   *    We expect to get an underflow(within a burst) async message.   */ -bool test_underflow_message(uhd::usrp::single_usrp::sptr sdev){ -    uhd::device::sptr dev = sdev->get_device(); +bool test_underflow_message(uhd::usrp::multi_usrp::sptr usrp){      std::cout << "Test underflow message... " << std::flush;      uhd::tx_metadata_t md; @@ -93,14 +91,14 @@ bool test_underflow_message(uhd::usrp::single_usrp::sptr sdev){      md.end_of_burst   = false;      md.has_time_spec  = false; -    dev->send( +    usrp->get_device()->send(          NULL, 0, md,          uhd::io_type_t::COMPLEX_FLOAT32,          uhd::device::SEND_MODE_FULL_BUFF      );      uhd::async_metadata_t async_md; -    if (not dev->recv_async_msg(async_md, 1)){ +    if (not usrp->get_device()->recv_async_msg(async_md, 1)){          std::cout << boost::format(              "failed:\n"              "    Async message recv timed out.\n" @@ -130,8 +128,7 @@ bool test_underflow_message(uhd::usrp::single_usrp::sptr sdev){   *    Send a burst packet that occurs at a time in the past.   *    We expect to get a time error async message.   */ -bool test_time_error_message(uhd::usrp::single_usrp::sptr sdev){ -    uhd::device::sptr dev = sdev->get_device(); +bool test_time_error_message(uhd::usrp::multi_usrp::sptr usrp){      std::cout << "Test time error message... " << std::flush;      uhd::tx_metadata_t md; @@ -140,16 +137,16 @@ bool test_time_error_message(uhd::usrp::single_usrp::sptr sdev){      md.has_time_spec  = true;      md.time_spec      = uhd::time_spec_t(100.0); //send at 100s -    sdev->set_time_now(uhd::time_spec_t(200.0)); //time at 200s +    usrp->set_time_now(uhd::time_spec_t(200.0)); //time at 200s -    dev->send( +    usrp->get_device()->send(          NULL, 0, md,          uhd::io_type_t::COMPLEX_FLOAT32,          uhd::device::SEND_MODE_FULL_BUFF      );      uhd::async_metadata_t async_md; -    if (not dev->recv_async_msg(async_md)){ +    if (not usrp->get_device()->recv_async_msg(async_md)){          std::cout << boost::format(              "failed:\n"              "    Async message recv timed out.\n" @@ -174,10 +171,9 @@ bool test_time_error_message(uhd::usrp::single_usrp::sptr sdev){      }  } -void flush_async_md(uhd::usrp::single_usrp::sptr sdev){ -    uhd::device::sptr dev = sdev->get_device(); +void flush_async_md(uhd::usrp::multi_usrp::sptr usrp){      uhd::async_metadata_t async_md; -    while (dev->recv_async_msg(async_md, 1.0)){} +    while (usrp->get_device()->recv_async_msg(async_md, 1.0)){}  }  int UHD_SAFE_MAIN(int argc, char *argv[]){ @@ -192,7 +188,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      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") +        ("args",   po::value<std::string>(&args)->default_value(""), "multi uhd device address args")          ("rate",   po::value<double>(&rate)->default_value(1.5e6),   "rate of outgoing samples")          ("ntests", po::value<size_t>(&ntests)->default_value(10),    "number of tests to run")      ; @@ -209,18 +205,18 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      //create a usrp device      std::cout << std::endl;      std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; -    uhd::usrp::single_usrp::sptr sdev = uhd::usrp::single_usrp::make(args); -    std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << 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;      //set the tx sample rate      std::cout << boost::format("Setting TX Rate: %f Msps...") % (rate/1e6) << std::endl; -    sdev->set_tx_rate(rate); -    std::cout << boost::format("Actual TX Rate: %f Msps...") % (sdev->get_tx_rate()/1e6) << std::endl << 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;      //------------------------------------------------------------------      // begin asyc messages test      //------------------------------------------------------------------ -    static const uhd::dict<std::string, boost::function<bool(uhd::usrp::single_usrp::sptr)> > +    static const uhd::dict<std::string, boost::function<bool(uhd::usrp::multi_usrp::sptr)> >          tests = boost::assign::map_list_of          ("Test Burst ACK ", &test_burst_ack_message)          ("Test Underflow ", &test_underflow_message) @@ -237,8 +233,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      //run the tests, pick at random      for (size_t n = 0; n < ntests; n++){          std::string key = tests.keys()[std::rand() % tests.size()]; -        bool pass = tests[key](sdev); -        flush_async_md(sdev); +        bool pass = tests[key](usrp); +        flush_async_md(usrp);          //store result          if (pass) successes[key]++; diff --git a/host/examples/test_pps_input.cpp b/host/examples/test_pps_input.cpp index 273c73df0..994b7ca87 100644 --- a/host/examples/test_pps_input.cpp +++ b/host/examples/test_pps_input.cpp @@ -1,5 +1,5 @@  // -// Copyright 2010 Ettus Research LLC +// Copyright 2010-2011 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 @@ -51,13 +51,12 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      //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 sdev = uhd::usrp::multi_usrp::make(args); -    uhd::device::sptr dev = sdev->get_device(); -    std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << 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;      //set the time at an unknown pps (will throw if no pps)      std::cout << std::endl << "Attempt to detect the PPS and set the time..." << std::endl << std::endl; -    sdev->set_time_unknown_pps(uhd::time_spec_t(0.0)); +    usrp->set_time_unknown_pps(uhd::time_spec_t(0.0));      std::cout << std::endl << "Success!" << std::endl << std::endl;      return 0;  } diff --git a/host/examples/tx_from_file.cpp b/host/examples/tx_from_file.cpp deleted file mode 100644 index 8af9b0f4a..000000000 --- a/host/examples/tx_from_file.cpp +++ /dev/null @@ -1,124 +0,0 @@ -// -// Copyright 2010-2011 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/>. -// - -#include <uhd/utils/thread_priority.hpp> -#include <uhd/utils/safe_main.hpp> -#include <uhd/usrp/simple_usrp.hpp> -#include <boost/program_options.hpp> -#include <boost/format.hpp> -#include <iostream> -#include <complex> -#include <fstream> - -namespace po = boost::program_options; - -int UHD_SAFE_MAIN(int argc, char *argv[]){ -    uhd::set_thread_priority_safe(); - -    //variables to be set by po -    std::string args; -    double seconds_in_future; -    size_t total_num_samps; -    size_t samps_per_packet; -    double tx_rate, freq, gain; -    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(""), "simple uhd device address args") -        ("secs", po::value<double>(&seconds_in_future)->default_value(3), "number of seconds in the future to transmit") -        ("nsamps", po::value<size_t>(&total_num_samps)->default_value(1000), "total number of samples to transmit") -        ("txrate", po::value<double>(&tx_rate)->default_value(100e6/16), "rate of outgoing samples") -        ("freq", po::value<double>(&freq)->default_value(0), "rf center frequency in Hz") -        ("ampl", po::value<float>(&l)->default_value(float(0.3)), "amplitude of each sample") -        ("gain", po::value<double>(&gain)->default_value(0), "amplitude of each sample") -        ("dilv", "specify to disable inner-loop verbose") -    ; -    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 Timed Samples %s") % desc << std::endl; -        return ~0; -    } - -    bool verbose = vm.count("dilv") == 0; - -    //create a usrp device -    std::cout << std::endl; -    std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; -    uhd::usrp::simple_usrp::sptr sdev = uhd::usrp::simple_usrp::make(args); -    uhd::device::sptr dev = sdev->get_device(); -    std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << std::endl; - -    //set properties on the device -    std::cout << boost::format("Setting TX Rate: %f Msps...") % (tx_rate/1e6) << std::endl; -    sdev->set_tx_rate(tx_rate); -    std::cout << boost::format("Actual TX Rate: %f Msps...") % (sdev->get_tx_rate()/1e6) << std::endl; -    std::cout << boost::format("Setting device timestamp to 0...") << std::endl; -    sdev->set_tx_freq(freq); -    sdev->set_time_now(uhd::time_spec_t(0.0)); - -    sdev->set_gain(gain); - -    //allocate data to send -    std::vector<std::complex<short> > buff; -    uhd::tx_metadata_t md; - -    std::cout << "Read data to send from file: in.dat" << std::endl; -    std::ifstream infile("in.dat", std::ifstream::binary); -    while (!infile.eof()) { -        std::complex<short> c; -        infile.read((char *)&c, sizeof(std::complex<short>)); -        if (!((c.real() == 0) && (c.imag() == 0))) { -            buff.push_back(c);  -//std::cout << "C = " << c << std::endl; -        } -    } -    samps_per_packet = buff.size(); -    infile.close(); -    std::cout << "Number of samples in file: " << samps_per_packet << std::endl; - -    //send the data in multiple packets -    size_t num_packets = (total_num_samps+samps_per_packet-1)/samps_per_packet; -    for (size_t i = 0; i < num_packets; i++){ -        //setup the metadata flags and time spec -        md.start_of_burst = (i == 0);              //only first packet has SOB -        md.end_of_burst   = (i == num_packets-1);  //only last packet has EOB -        md.has_time_spec  = (i == 0);              //only first packet has time -        md.time_spec = uhd::time_spec_t(seconds_in_future); - -        size_t samps_to_send = std::min(total_num_samps - samps_per_packet*i, samps_per_packet); - -        //send the entire packet (driver fragments internally) -        size_t num_tx_samps = dev->send( -            &buff.front(), samps_to_send, md, -            uhd::io_type_t::COMPLEX_INT16, -            uhd::device::SEND_MODE_FULL_BUFF -        ); -        if(verbose) std::cout << std::endl << boost::format("Sent %d samples") % num_tx_samps << std::endl; -    } - -    //finished -    std::cout << std::endl << "Done!" << std::endl << std::endl; - -    return 0; -} diff --git a/host/examples/tx_timed_samples.cpp b/host/examples/tx_timed_samples.cpp index 6d6aa7010..f10d7e4ea 100644 --- a/host/examples/tx_timed_samples.cpp +++ b/host/examples/tx_timed_samples.cpp @@ -17,8 +17,9 @@  #include <uhd/utils/thread_priority.hpp>  #include <uhd/utils/safe_main.hpp> -#include <uhd/usrp/single_usrp.hpp> +#include <uhd/usrp/multi_usrp.hpp>  #include <boost/program_options.hpp> +#include <boost/thread/thread.hpp>  #include <boost/format.hpp>  #include <iostream>  #include <complex> @@ -64,22 +65,21 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      //create a usrp device      std::cout << std::endl;      std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; -    uhd::usrp::single_usrp::sptr sdev = uhd::usrp::single_usrp::make(args); -    uhd::device::sptr dev = sdev->get_device(); -    std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << 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;      //set the tx sample rate      std::cout << boost::format("Setting TX Rate: %f Msps...") % (rate/1e6) << std::endl; -    sdev->set_tx_rate(rate); -    std::cout << boost::format("Actual TX Rate: %f Msps...") % (sdev->get_tx_rate()/1e6) << std::endl << 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 tx center frequency      std::cout << boost::format("Setting TX Freq: %f Mhz...") % (freq/1e6) << std::endl; -    sdev->set_tx_freq(freq); -    std::cout << boost::format("Actual TX Freq: %f Mhz...") % (sdev->get_tx_freq()/1e6) << std::endl << std::endl; +    usrp->set_tx_freq(freq); +    std::cout << boost::format("Actual TX Freq: %f Mhz...") % (usrp->get_tx_freq()/1e6) << std::endl << std::endl;      std::cout << boost::format("Setting device timestamp to 0...") << std::endl; -    sdev->set_time_now(uhd::time_spec_t(0.0)); +    usrp->set_time_now(uhd::time_spec_t(0.0));      //allocate data to send      std::vector<std::complex<float> > buff(samps_per_packet, std::complex<float>(ampl, ampl)); @@ -99,7 +99,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){          size_t samps_to_send = std::min(total_num_samps - samps_per_packet*i, samps_per_packet);          //send the entire packet (driver fragments internally) -        size_t num_tx_samps = dev->send( +        size_t num_tx_samps = usrp->get_device()->send(              &buff.front(), samps_to_send, md,              uhd::io_type_t::COMPLEX_FLOAT32,              uhd::device::SEND_MODE_FULL_BUFF, @@ -110,6 +110,9 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){          if(verbose) std::cout << std::endl << boost::format("Sent %d samples") % num_tx_samps << std::endl;      } +    //ensure that the buffers have flushed out to the device before deconstruction +    boost::this_thread::sleep(boost::posix_time::seconds(1)); +      //finished      std::cout << std::endl << "Done!" << std::endl << std::endl; diff --git a/host/examples/tx_waveforms.cpp b/host/examples/tx_waveforms.cpp index 553d6739d..dd18d3174 100644 --- a/host/examples/tx_waveforms.cpp +++ b/host/examples/tx_waveforms.cpp @@ -18,7 +18,7 @@  #include <uhd/utils/thread_priority.hpp>  #include <uhd/utils/safe_main.hpp>  #include <uhd/utils/static.hpp> -#include <uhd/usrp/single_usrp.hpp> +#include <uhd/usrp/multi_usrp.hpp>  #include <boost/program_options.hpp>  #include <boost/thread/thread_time.hpp> //system time  #include <boost/math/special_functions/round.hpp> @@ -93,35 +93,34 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      //create a usrp device      std::cout << std::endl;      std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; -    uhd::usrp::single_usrp::sptr sdev = uhd::usrp::single_usrp::make(args); -    uhd::device::sptr dev = sdev->get_device(); -    std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << 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;      //set the tx sample rate      std::cout << boost::format("Setting TX Rate: %f Msps...") % (rate/1e6) << std::endl; -    sdev->set_tx_rate(rate); -    std::cout << boost::format("Actual TX Rate: %f Msps...") % (sdev->get_tx_rate()/1e6) << std::endl << 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 tx center frequency      std::cout << boost::format("Setting TX Freq: %f Mhz...") % (freq/1e6) << std::endl; -    sdev->set_tx_freq(freq); -    std::cout << boost::format("Actual TX Freq: %f Mhz...") % (sdev->get_tx_freq()/1e6) << std::endl << std::endl; +    usrp->set_tx_freq(freq); +    std::cout << boost::format("Actual TX Freq: %f Mhz...") % (usrp->get_tx_freq()/1e6) << std::endl << std::endl;      //set the tx rf gain      std::cout << boost::format("Setting TX Gain: %f dB...") % gain << std::endl; -    sdev->set_tx_gain(gain); -    std::cout << boost::format("Actual TX Gain: %f dB...") % sdev->get_tx_gain() << std::endl << std::endl; +    usrp->set_tx_gain(gain); +    std::cout << boost::format("Actual TX Gain: %f dB...") % usrp->get_tx_gain() << std::endl << std::endl;      //for the const wave, set the wave freq for small samples per period      if (wave_freq == 0 and wave_type == "CONST"){ -        wave_freq = sdev->get_tx_rate()/2; +        wave_freq = usrp->get_tx_rate()/2;      }      //error when the waveform is not possible to generate -    if (std::abs(wave_freq) > sdev->get_tx_rate()/2){ +    if (std::abs(wave_freq) > usrp->get_tx_rate()/2){          throw std::runtime_error("wave freq out of Nyquist zone");      } -    if (sdev->get_tx_rate()/std::abs(wave_freq) > sine_table_len/2 and wave_type == "SINE"){ +    if (usrp->get_tx_rate()/std::abs(wave_freq) > sine_table_len/2 and wave_type == "SINE"){          throw std::runtime_error("sine freq too small for table");      } @@ -135,7 +134,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      //allocate the buffer and precalculate values      std::vector<std::complex<float> > buff(spb); -    const float cps = float(wave_freq/sdev->get_tx_rate()); +    const float cps = float(wave_freq/usrp->get_tx_rate());      const float i_off = (wave_freq > 0)? float(0.25) : 0;      const float q_off = (wave_freq < 0)? float(0.25) : 0;      float theta = 0; @@ -162,7 +161,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){          theta = std::fmod(theta, 1);          //send the entire contents of the buffer -        dev->send( +        usrp->get_device()->send(              &buff.front(), buff.size(), md,              uhd::io_type_t::COMPLEX_FLOAT32,              uhd::device::SEND_MODE_FULL_BUFF @@ -172,7 +171,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      //send a mini EOB packet      md.start_of_burst = false;      md.end_of_burst   = true; -    dev->send(NULL, 0, md, +    usrp->get_device()->send(NULL, 0, md,          uhd::io_type_t::COMPLEX_FLOAT32,          uhd::device::SEND_MODE_FULL_BUFF      ); diff --git a/host/include/uhd/transport/bounded_buffer.ipp b/host/include/uhd/transport/bounded_buffer.ipp index f7915d866..4fbe3f085 100644 --- a/host/include/uhd/transport/bounded_buffer.ipp +++ b/host/include/uhd/transport/bounded_buffer.ipp @@ -22,6 +22,7 @@  #include <boost/function.hpp>  #include <boost/circular_buffer.hpp>  #include <boost/thread/condition.hpp> +#include <boost/thread/locks.hpp>  #include <boost/date_time/posix_time/posix_time_types.hpp>  namespace uhd{ namespace transport{ namespace{ /*anon*/ @@ -36,7 +37,7 @@ namespace uhd{ namespace transport{ namespace{ /*anon*/          }          UHD_INLINE bool push_with_pop_on_full(const elem_type &elem){ -            boost::unique_lock<boost::mutex> lock(_mutex); +            boost::mutex::scoped_lock lock(_mutex);              if(_buffer.full()){                  _buffer.pop_back();                  _buffer.push_front(elem); @@ -53,7 +54,7 @@ namespace uhd{ namespace transport{ namespace{ /*anon*/          }          UHD_INLINE void push_with_wait(const elem_type &elem){ -            boost::unique_lock<boost::mutex> lock(_mutex); +            boost::mutex::scoped_lock lock(_mutex);              _full_cond.wait(lock, _not_full_fcn);              _buffer.push_front(elem);              lock.unlock(); @@ -61,7 +62,7 @@ namespace uhd{ namespace transport{ namespace{ /*anon*/          }          UHD_INLINE bool push_with_timed_wait(const elem_type &elem, double timeout){ -            boost::unique_lock<boost::mutex> lock(_mutex); +            boost::mutex::scoped_lock lock(_mutex);              if (not _full_cond.timed_wait(                  lock, to_time_dur(timeout), _not_full_fcn              )) return false; @@ -72,7 +73,7 @@ namespace uhd{ namespace transport{ namespace{ /*anon*/          }          UHD_INLINE void pop_with_wait(elem_type &elem){ -            boost::unique_lock<boost::mutex> lock(_mutex); +            boost::mutex::scoped_lock lock(_mutex);              _empty_cond.wait(lock, _not_empty_fcn);              elem = this->pop_back();              lock.unlock(); @@ -80,7 +81,7 @@ namespace uhd{ namespace transport{ namespace{ /*anon*/          }          UHD_INLINE bool pop_with_timed_wait(elem_type &elem, double timeout){ -            boost::unique_lock<boost::mutex> lock(_mutex); +            boost::mutex::scoped_lock lock(_mutex);              if (not _empty_cond.timed_wait(                  lock, to_time_dur(timeout), _not_empty_fcn              )) return false; @@ -91,7 +92,7 @@ namespace uhd{ namespace transport{ namespace{ /*anon*/          }          UHD_INLINE void clear(void){ -            boost::unique_lock<boost::mutex> lock(_mutex); +            boost::mutex::scoped_lock lock(_mutex);              while (not_empty()) this->pop_back();              lock.unlock();              _full_cond.notify_one(); diff --git a/host/include/uhd/types/io_type.hpp b/host/include/uhd/types/io_type.hpp index 5176374d6..ec1b9c056 100644 --- a/host/include/uhd/types/io_type.hpp +++ b/host/include/uhd/types/io_type.hpp @@ -1,5 +1,5 @@  // -// Copyright 2010 Ettus Research LLC +// Copyright 2010-2011 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 @@ -33,9 +33,13 @@ namespace uhd{           * Built in IO types known to the system.           */          enum tid_t{ +            //! Custom type (technically unsupported by implementation)              CUSTOM_TYPE =     '?', +            //! Complex floating point (32-bit floats) range [-1.0, +1.0]              COMPLEX_FLOAT32 = 'f', +            //! Complex signed integer (16-bit integers) range [-32768, +32767]              COMPLEX_INT16 =   's', +            //! Complex signed integer (8-bit integers) range [-128, 127]              COMPLEX_INT8 =    'b'          }; diff --git a/host/include/uhd/usrp/dboard_iface.hpp b/host/include/uhd/usrp/dboard_iface.hpp index cfb727017..c5898365d 100644 --- a/host/include/uhd/usrp/dboard_iface.hpp +++ b/host/include/uhd/usrp/dboard_iface.hpp @@ -28,6 +28,27 @@  namespace uhd{ namespace usrp{ +//! Special properties that differentiate this daughterboard slot +struct UHD_API dboard_iface_special_props_t{ +    /*! +     * Soft clock divider: +     * When a motherboard cannot provided a divided dboard clock, +     * it may provided a "soft" divided clock over an FPGA GPIO. +     * The implementation must know the type of clock provided. +     */ +    bool soft_clock_divider; + +    /*! +     * Mangle i2c addresses: +     * When i2c is shared across multiple daugterboard slots, +     * the i2c addresses will be mangled on the secondary slot +     * to avoid conflicts between slots in the i2c address space. +     * The mangling is daguhterboard specific so the implementation +     * needs to know whether it should use mangled addresses or not. +     */ +    bool mangle_i2c_addrs; +}; +  /*!   * The daughter board dboard interface to be subclassed.   * A dboard instance interfaces with the mboard though this api. @@ -37,6 +58,7 @@ namespace uhd{ namespace usrp{  class UHD_API dboard_iface{  public:      typedef boost::shared_ptr<dboard_iface> sptr; +    typedef dboard_iface_special_props_t special_props_t;      //! tells the host which unit to use      enum unit_t{ @@ -66,27 +88,6 @@ public:          AUX_ADC_B = 'b'      }; -    //! Special properties that differentiate this daughterboard slot -    struct special_props_t{ -        /*! -         * Soft clock divider: -         * When a motherboard cannot provided a divided dboard clock, -         * it may provided a "soft" divided clock over an FPGA GPIO. -         * The implementation must know the type of clock provided. -         */ -        bool soft_clock_divider; - -        /*! -         * Mangle i2c addresses: -         * When i2c is shared across multiple daugterboard slots, -         * the i2c addresses will be mangled on the secondary slot -         * to avoid conflicts between slots in the i2c address space. -         * The mangling is daguhterboard specific so the implementation -         * needs to know whether it should use mangled addresses or not. -         */ -        bool mangle_i2c_addrs; -    }; -      /*!       * Get special properties information for this dboard slot.       * This call helps the dboard code to handle implementation diff --git a/host/include/uhd/usrp/mboard_props.hpp b/host/include/uhd/usrp/mboard_props.hpp index c82bfc21a..d04ad012c 100644 --- a/host/include/uhd/usrp/mboard_props.hpp +++ b/host/include/uhd/usrp/mboard_props.hpp @@ -31,6 +31,7 @@ namespace uhd{ namespace usrp{      enum mboard_prop_t{          MBOARD_PROP_NAME            = 'n', //ro, std::string          MBOARD_PROP_OTHERS          = 'o', //ro, prop_names_t +        MBOARD_PROP_CLOCK_RATE      = 'c', //rw, double          MBOARD_PROP_RX_DSP          = 'd', //ro, wax::obj          MBOARD_PROP_RX_DSP_NAMES    = 'D', //ro, prop_names_t          MBOARD_PROP_TX_DSP          = 'u', //ro, wax::obj diff --git a/host/include/uhd/usrp/multi_usrp.hpp b/host/include/uhd/usrp/multi_usrp.hpp index b603d4324..c77b5d6d2 100644 --- a/host/include/uhd/usrp/multi_usrp.hpp +++ b/host/include/uhd/usrp/multi_usrp.hpp @@ -34,19 +34,30 @@  namespace uhd{ namespace usrp{  /*! - * The multi-USRP device class: - * A multi-USRP facilitates ease-of-use for multiple USRP scenarios. - * The wrapper provides convenience functions to control the group - * of underlying devices as if they consisted of a single device. + * The Multi-USRP device class:   * - * A few notes about a multi-USRP configuration: + * This class facilitates ease-of-use for most use-case scenarios. + * The wrapper provides convenience functions to tune the devices, + * set the dboard gains, antennas, filters, and other properties. + * This class can be used to interface with a single USRP with + * one or more channels, or multiple USRPs in a homogeneous setup. + * All members take an optional parameter for board number or channel number. + * In the single device, single channel case, these parameters can be unspecified. + * + * When using a single device with multiple channels: + *  - Channel mapping is determined by the subdevice specifications + *  - All channels share a common RX sample rate + *  - All channels share a common TX sample rate + * + * When using multiple devices in a configuration: + *  - Channel mapping is determined by the device address arguments   *  - All boards share a common RX sample rate   *  - All boards share a common TX sample rate   *  - All boards share a common RX subdevice specification size   *  - All boards share a common TX subdevice specification size   *  - All boards must have synchronized times (see the set_time_*() calls)   * - * Example to setup channel mapping: + * Example to setup channel mapping for multiple devices:   * <pre>   *   * //create a multi_usrp with two boards in the configuration @@ -95,6 +106,26 @@ public:      /*******************************************************************       * Mboard methods       ******************************************************************/ + +    /*! +     * Set the master clock rate. +     * This controls the rate of the clock that feeds the FPGA DSP. +     * On some devices, this re-tunes the clock to the specified rate. +     * If the specified rate is not available, this method will throw. +     * On other devices, this method notifies the software of the rate, +     * but requires the the user has made the necessary hardware change. +     * \param rate the new master clock rate in Hz +     * \param mboard the motherboard index 0 to M-1 +     */ +    virtual void set_master_clock_rate(double rate, size_t mboard = ALL_MBOARDS) = 0; + +    /*! +     * Get the master clock rate. +     * \param mboard the motherboard index 0 to M-1 +     * \return the master clock rate in Hz. +     */ +    virtual double get_master_clock_rate(size_t mboard = 0) = 0; +      /*!       * Get a printable summary for this USRP configuration.       * \return a printable string @@ -106,7 +137,7 @@ public:       * \param mboard which motherboard to query       * \return a string representing the name       */ -    virtual std::string get_mboard_name(size_t mboard) = 0; +    virtual std::string get_mboard_name(size_t mboard = 0) = 0;      /*!       * Get the current time in the usrp time registers. @@ -121,6 +152,19 @@ public:      virtual time_spec_t get_time_last_pps(void) = 0;      /*! +     * Sets the time registers on the usrp immediately. +     * +     * If only one MIMO master is present in your configuration, set_time_now is +     * safe to use because the slave's time automatically follows the master's time. +     * Otherwise, this call cannot set the time synchronously across multiple devices. +     * Please use the set_time_next_pps or set_time_unknown_pps calls with a PPS signal. +     * +     * \param time_spec the time to latch into the usrp device +     * \param mboard the motherboard index 0 to M-1 +     */ +    virtual void set_time_now(const time_spec_t &time_spec, size_t mboard = ALL_MBOARDS) = 0; + +    /*!       * Set the time registers on the usrp at the next pps tick.       * The values will not be latched in until the pulse occurs.       * It is recommended that the user sleep(1) after calling to ensure @@ -162,6 +206,11 @@ public:       * Issue a stream command to the usrp device.       * This tells the usrp to send samples into the host.       * See the documentation for stream_cmd_t for more info. +     * +     * With multiple devices, the first stream command in a chain of commands +     * should have a time spec in the near future and stream_now = false; +     * to ensure that the packets can be aligned by their time specs. +     *       * \param stream_cmd the stream command to issue       */      virtual void issue_stream_cmd(const stream_cmd_t &stream_cmd) = 0; @@ -173,7 +222,7 @@ public:       * \param clock_config the clock configuration to set       * \param mboard which motherboard to set the config       */ -    virtual void set_clock_config(const clock_config_t &clock_config, size_t mboard) = 0; +    virtual void set_clock_config(const clock_config_t &clock_config, size_t mboard = ALL_MBOARDS) = 0;      /*!       * Get the number of USRP motherboards in this configuration. @@ -191,14 +240,14 @@ public:       * \param spec the new subdevice specification       * \param mboard the motherboard index 0 to M-1       */ -    virtual void set_rx_subdev_spec(const uhd::usrp::subdev_spec_t &spec, size_t mboard) = 0; +    virtual void set_rx_subdev_spec(const uhd::usrp::subdev_spec_t &spec, size_t mboard = ALL_MBOARDS) = 0;      /*!       * Get the RX subdevice specification.       * \param mboard the motherboard index 0 to M-1       * \return the subdevice specification in use       */ -    virtual uhd::usrp::subdev_spec_t get_rx_subdev_spec(size_t mboard) = 0; +    virtual uhd::usrp::subdev_spec_t get_rx_subdev_spec(size_t mboard = 0) = 0;      /*!       * Get the number of RX channels in this configuration. @@ -212,7 +261,7 @@ public:       * \param chan the channel index 0 to N-1       * \return the subdevice name       */ -    virtual std::string get_rx_subdev_name(size_t chan) = 0; +    virtual std::string get_rx_subdev_name(size_t chan = 0) = 0;      /*!       * Set the RX sample rate across all channels. @@ -241,14 +290,14 @@ public:       * \param chan the channel index 0 to N-1       * \return the frequency in Hz       */ -    virtual double get_rx_freq(size_t chan) = 0; +    virtual double get_rx_freq(size_t chan = 0) = 0;      /*!       * Get the RX center frequency range.       * \param chan the channel index 0 to N-1       * \return a frequency range object       */ -    virtual freq_range_t get_rx_freq_range(size_t chan) = 0; +    virtual freq_range_t get_rx_freq_range(size_t chan = 0) = 0;      /*!       * Set the RX gain value for the specified gain element. @@ -257,10 +306,10 @@ public:       * \param name the name of the gain element       * \param chan the channel index 0 to N-1       */ -    virtual void set_rx_gain(double gain, const std::string &name, size_t chan) = 0; +    virtual void set_rx_gain(double gain, const std::string &name, size_t chan = 0) = 0;      //! A convenience wrapper for setting overall RX gain -    void set_rx_gain(double gain, size_t chan){ +    void set_rx_gain(double gain, size_t chan = 0){          return this->set_rx_gain(gain, ALL_GAINS, chan);      } @@ -271,10 +320,10 @@ public:       * \param chan the channel index 0 to N-1       * \return the gain in dB       */ -    virtual double get_rx_gain(const std::string &name, size_t chan) = 0; +    virtual double get_rx_gain(const std::string &name, size_t chan = 0) = 0;      //! A convenience wrapper for getting overall RX gain -    double get_rx_gain(size_t chan){ +    double get_rx_gain(size_t chan = 0){          return this->get_rx_gain(ALL_GAINS, chan);      } @@ -285,10 +334,10 @@ public:       * \param chan the channel index 0 to N-1       * \return a gain range object       */ -    virtual gain_range_t get_rx_gain_range(const std::string &name, size_t chan) = 0; +    virtual gain_range_t get_rx_gain_range(const std::string &name, size_t chan = 0) = 0;      //! A convenience wrapper for getting overall RX gain range -    gain_range_t get_rx_gain_range(size_t chan){ +    gain_range_t get_rx_gain_range(size_t chan = 0){          return this->get_rx_gain_range(ALL_GAINS, chan);      } @@ -298,49 +347,49 @@ public:       * \param chan the channel index 0 to N-1       * \return a vector of gain element names       */ -    virtual std::vector<std::string> get_rx_gain_names(size_t chan) = 0; +    virtual std::vector<std::string> get_rx_gain_names(size_t chan = 0) = 0;      /*!       * Select the RX antenna on the subdevice.       * \param ant the antenna name       * \param chan the channel index 0 to N-1       */ -    virtual void set_rx_antenna(const std::string &ant, size_t chan) = 0; +    virtual void set_rx_antenna(const std::string &ant, size_t chan = 0) = 0;      /*!       * Get the selected RX antenna on the subdevice.       * \param chan the channel index 0 to N-1       * \return the antenna name       */ -    virtual std::string get_rx_antenna(size_t chan) = 0; +    virtual std::string get_rx_antenna(size_t chan = 0) = 0;      /*!       * Get a list of possible RX antennas on the subdevice.       * \param chan the channel index 0 to N-1       * \return a vector of antenna names       */ -    virtual std::vector<std::string> get_rx_antennas(size_t chan) = 0; +    virtual std::vector<std::string> get_rx_antennas(size_t chan = 0) = 0;      /*!       * Get the locked status of the LO on the subdevice.       * \param chan the channel index 0 to N-1       * \return true for locked       */ -    virtual bool get_rx_lo_locked(size_t chan) = 0; +    virtual bool get_rx_lo_locked(size_t chan = 0) = 0;      /*!       * Set the RX bandwidth on the subdevice.       * \param bandwidth the bandwidth in Hz       * \param chan the channel index 0 to N-1       */ -    virtual void set_rx_bandwidth(double bandwidth, size_t chan) = 0; +    virtual void set_rx_bandwidth(double bandwidth, size_t chan = 0) = 0;      /*!       * Get the RX bandwidth on the subdevice.       * \param chan the channel index 0 to N-1       * \return the bandwidth in Hz       */ -    virtual double get_rx_bandwidth(size_t chan) = 0; +    virtual double get_rx_bandwidth(size_t chan = 0) = 0;      /*!       * Read the RSSI value on the RX subdevice. @@ -348,7 +397,7 @@ public:       * \return the rssi in dB       * \throw exception if RSSI readback not supported       */ -    virtual double read_rssi(size_t chan) = 0; +    virtual double read_rssi(size_t chan = 0) = 0;      /*!       * Get the dboard interface object for the RX subdevice. @@ -357,7 +406,7 @@ public:       * \param chan the channel index 0 to N-1       * \return the dboard interface sptr       */ -    virtual dboard_iface::sptr get_rx_dboard_iface(size_t chan) = 0; +    virtual dboard_iface::sptr get_rx_dboard_iface(size_t chan = 0) = 0;      /*******************************************************************       * TX methods @@ -370,14 +419,14 @@ public:       * \param spec the new subdevice specification       * \param mboard the motherboard index 0 to M-1       */ -    virtual void set_tx_subdev_spec(const uhd::usrp::subdev_spec_t &spec, size_t mboard) = 0; +    virtual void set_tx_subdev_spec(const uhd::usrp::subdev_spec_t &spec, size_t mboard = ALL_MBOARDS) = 0;      /*!       * Get the TX subdevice specification.       * \param mboard the motherboard index 0 to M-1       * \return the subdevice specification in use       */ -    virtual uhd::usrp::subdev_spec_t get_tx_subdev_spec(size_t mboard) = 0; +    virtual uhd::usrp::subdev_spec_t get_tx_subdev_spec(size_t mboard = 0) = 0;      /*!       * Get the number of TX channels in this configuration. @@ -391,7 +440,7 @@ public:       * \param chan the channel index 0 to N-1       * \return the subdevice name       */ -    virtual std::string get_tx_subdev_name(size_t chan) = 0; +    virtual std::string get_tx_subdev_name(size_t chan = 0) = 0;      /*!       * Set the TX sample rate across all channels. @@ -420,14 +469,14 @@ public:       * \param chan the channel index 0 to N-1       * \return the frequency in Hz       */ -    virtual double get_tx_freq(size_t chan) = 0; +    virtual double get_tx_freq(size_t chan = 0) = 0;      /*!       * Get the TX center frequency range.       * \param chan the channel index 0 to N-1       * \return a frequency range object       */ -    virtual freq_range_t get_tx_freq_range(size_t chan) = 0; +    virtual freq_range_t get_tx_freq_range(size_t chan = 0) = 0;      /*!       * Set the TX gain value for the specified gain element. @@ -436,10 +485,10 @@ public:       * \param name the name of the gain element       * \param chan the channel index 0 to N-1       */ -    virtual void set_tx_gain(double gain, const std::string &name, size_t chan) = 0; +    virtual void set_tx_gain(double gain, const std::string &name, size_t chan = 0) = 0;      //! A convenience wrapper for setting overall TX gain -    void set_tx_gain(double gain, size_t chan){ +    void set_tx_gain(double gain, size_t chan = 0){          return this->set_tx_gain(gain, ALL_GAINS, chan);      } @@ -450,10 +499,10 @@ public:       * \param chan the channel index 0 to N-1       * \return the gain in dB       */ -    virtual double get_tx_gain(const std::string &name, size_t chan) = 0; +    virtual double get_tx_gain(const std::string &name, size_t chan = 0) = 0;      //! A convenience wrapper for getting overall TX gain -    double get_tx_gain(size_t chan){ +    double get_tx_gain(size_t chan = 0){          return this->get_tx_gain(ALL_GAINS, chan);      } @@ -464,10 +513,10 @@ public:       * \param chan the channel index 0 to N-1       * \return a gain range object       */ -    virtual gain_range_t get_tx_gain_range(const std::string &name, size_t chan) = 0; +    virtual gain_range_t get_tx_gain_range(const std::string &name, size_t chan = 0) = 0;      //! A convenience wrapper for getting overall TX gain range -    gain_range_t get_tx_gain_range(size_t chan){ +    gain_range_t get_tx_gain_range(size_t chan = 0){          return this->get_tx_gain_range(ALL_GAINS, chan);      } @@ -477,49 +526,49 @@ public:       * \param chan the channel index 0 to N-1       * \return a vector of gain element names       */ -    virtual std::vector<std::string> get_tx_gain_names(size_t chan) = 0; +    virtual std::vector<std::string> get_tx_gain_names(size_t chan = 0) = 0;      /*!       * Select the TX antenna on the subdevice.       * \param ant the antenna name       * \param chan the channel index 0 to N-1       */ -    virtual void set_tx_antenna(const std::string &ant, size_t chan) = 0; +    virtual void set_tx_antenna(const std::string &ant, size_t chan = 0) = 0;      /*!       * Get the selected TX antenna on the subdevice.       * \param chan the channel index 0 to N-1       * \return the antenna name       */ -    virtual std::string get_tx_antenna(size_t chan) = 0; +    virtual std::string get_tx_antenna(size_t chan = 0) = 0;      /*!       * Get a list of possible TX antennas on the subdevice.       * \param chan the channel index 0 to N-1       * \return a vector of antenna names       */ -    virtual std::vector<std::string> get_tx_antennas(size_t chan) = 0; +    virtual std::vector<std::string> get_tx_antennas(size_t chan = 0) = 0;      /*!       * Get the locked status of the LO on the subdevice.       * \param chan the channel index 0 to N-1       * \return true for locked       */ -    virtual bool get_tx_lo_locked(size_t chan) = 0; +    virtual bool get_tx_lo_locked(size_t chan = 0) = 0;      /*!       * Set the TX bandwidth on the subdevice.       * \param bandwidth the bandwidth in Hz       * \param chan the channel index 0 to N-1       */ -    virtual void set_tx_bandwidth(double bandwidth, size_t chan) = 0; +    virtual void set_tx_bandwidth(double bandwidth, size_t chan = 0) = 0;      /*!       * Get the TX bandwidth on the subdevice.       * \param chan the channel index 0 to N-1       * \return the bandwidth in Hz       */ -    virtual double get_tx_bandwidth(size_t chan) = 0; +    virtual double get_tx_bandwidth(size_t chan = 0) = 0;      /*!       * Get the dboard interface object for the TX subdevice. @@ -528,7 +577,7 @@ public:       * \param chan the channel index 0 to N-1       * \return the dboard interface sptr       */ -    virtual dboard_iface::sptr get_tx_dboard_iface(size_t chan) = 0; +    virtual dboard_iface::sptr get_tx_dboard_iface(size_t chan = 0) = 0;  };  }} diff --git a/host/include/uhd/usrp/single_usrp.hpp b/host/include/uhd/usrp/single_usrp.hpp index d80999300..0520db162 100644 --- a/host/include/uhd/usrp/single_usrp.hpp +++ b/host/include/uhd/usrp/single_usrp.hpp @@ -18,441 +18,12 @@  #ifndef INCLUDED_UHD_USRP_SINGLE_USRP_HPP  #define INCLUDED_UHD_USRP_SINGLE_USRP_HPP -#include <uhd/config.hpp> -#include <uhd/device.hpp> -#include <uhd/types/ranges.hpp> -#include <uhd/types/stream_cmd.hpp> -#include <uhd/types/clock_config.hpp> -#include <uhd/types/tune_request.hpp> -#include <uhd/types/tune_result.hpp> -#include <uhd/usrp/subdev_spec.hpp> -#include <uhd/usrp/dboard_iface.hpp> -#include <boost/shared_ptr.hpp> -#include <boost/utility.hpp> -#include <vector> +#include <uhd/usrp/multi_usrp.hpp>  namespace uhd{ namespace usrp{ -/*! - * The single-USRP device class: - * A single-USRP facilitates ease-of-use for most use-case scenarios. - * The wrapper provides convenience functions to tune the devices - * as well as to set the dboard gains, antennas, and other properties. - * This wrapper supports multi-channel configurations per motherboard. - */ -class UHD_API single_usrp : boost::noncopyable{ -public: -    typedef boost::shared_ptr<single_usrp> sptr; - -    //! A wildcard gain element name -    static const std::string ALL_GAINS; - -    /*! -     * Make a new single usrp from the device address. -     * \param dev_addr the device address -     * \return a new single usrp object -     */ -    static sptr make(const device_addr_t &dev_addr); - -    /*! -     * Get the underlying device object. -     * This is needed to get access to the streaming API and properties. -     * \return the device object within this single usrp -     */ -    virtual device::sptr get_device(void) = 0; - -    /******************************************************************* -     * Mboard methods -     ******************************************************************/ -    /*! -     * Get a printable summary for this USRP configuration. -     * \return a printable string -     */ -    virtual std::string get_pp_string(void) = 0; - -    /*! -     * Get canonical name for this USRP motherboard. -     * \return a string representing the name -     */ -    virtual std::string get_mboard_name(void) = 0; - -    /*! -     * Get the current time in the usrp time registers. -     * \return a timespec representing current usrp time -     */ -    virtual time_spec_t get_time_now(void) = 0; - -    /*! -     * Get the time when the last pps pulse occured. -     * \return a timespec representing the last pps -     */ -    virtual time_spec_t get_time_last_pps(void) = 0; - -    /*! -     * Sets the time registers on the usrp immediately. -     * \param time_spec the time to latch into the usrp device -     */ -    virtual void set_time_now(const time_spec_t &time_spec) = 0; - -    /*! -     * Set the time registers on the usrp at the next pps tick. -     * The values will not be latched in until the pulse occurs. -     * It is recommended that the user sleep(1) after calling to ensure -     * that the time registers will be in a known state prior to use. -     * -     * Note: Because this call sets the time on the "next" pps, -     * the seconds in the time spec should be current seconds + 1. -     * -     * \param time_spec the time to latch into the usrp device -     */ -    virtual void set_time_next_pps(const time_spec_t &time_spec) = 0; - -    /*! -     * Issue a stream command to the usrp device. -     * This tells the usrp to send samples into the host. -     * See the documentation for stream_cmd_t for more info. -     * \param stream_cmd the stream command to issue -     */ -    virtual void issue_stream_cmd(const stream_cmd_t &stream_cmd) = 0; - -    /*! -     * Set the clock configuration for the usrp device. -     * This tells the usrp how to get a 10Mhz reference and PPS clock. -     * See the documentation for clock_config_t for more info. -     * \param clock_config the clock configuration to set -     */ -    virtual void set_clock_config(const clock_config_t &clock_config) = 0; - -    /******************************************************************* -     * RX methods -     ******************************************************************/ -    /*! -     * Set the RX subdevice specification: -     * The subdev spec maps a physical part of a daughter-board to a channel number. -     * Set the subdev spec before calling into any methods with a channel number. -     * \param spec the new subdevice specification -     */ -    virtual void set_rx_subdev_spec(const uhd::usrp::subdev_spec_t &spec) = 0; - -    /*! -     * Get the RX subdevice specification. -     * \return the subdevice specification in use -     */ -    virtual uhd::usrp::subdev_spec_t get_rx_subdev_spec(void) = 0; - -    /*! -     * Get the name of the RX subdevice. -     * \param chan the channel index 0 to N-1 -     * \return the subdevice name -     */ -    virtual std::string get_rx_subdev_name(size_t chan = 0) = 0; - -    /*! -     * Set the RX sample rate across all channels. -     * \param rate the rate in Sps -     */ -    virtual void set_rx_rate(double rate) = 0; - -    /*! -     * Gets the RX sample rate for all channels. -     * \return the rate in Sps -     */ -    virtual double get_rx_rate(void) = 0; - -    /*! -     * Set the RX center frequency. -     * \param tune_request tune request instructions -     * \param chan the channel index 0 to N-1 -     * \return a tune result object -     */ -    virtual tune_result_t set_rx_freq( -        const tune_request_t &tune_request, size_t chan = 0 -    ) = 0; - -    /*! -     * Get the RX center frequency. -     * \param chan the channel index 0 to N-1 -     * \return the frequency in Hz -     */ -    virtual double get_rx_freq(size_t chan = 0) = 0; - -    /*! -     * Get the RX center frequency range. -     * \param chan the channel index 0 to N-1 -     * \return a frequency range object -     */ -    virtual freq_range_t get_rx_freq_range(size_t chan = 0) = 0; - -    /*! -     * Set the RX gain value for the specified gain element. -     * For an empty name, distribute across all gain elements. -     * \param gain the gain in dB -     * \param name the name of the gain element -     * \param chan the channel index 0 to N-1 -     */ -    virtual void set_rx_gain(double gain, const std::string &name, size_t chan = 0) = 0; - -    //! A convenience wrapper for setting overall RX gain -    void set_rx_gain(double gain, size_t chan = 0){ -        return this->set_rx_gain(gain, ALL_GAINS, chan); -    } - -    /*! -     * Get the RX gain value for the specified gain element. -     * For an empty name, sum across all gain elements. -     * \param name the name of the gain element -     * \param chan the channel index 0 to N-1 -     * \return the gain in dB -     */ -    virtual double get_rx_gain(const std::string &name, size_t chan = 0) = 0; - -    //! A convenience wrapper for getting overall RX gain -    double get_rx_gain(size_t chan = 0){ -        return this->get_rx_gain(ALL_GAINS, chan); -    } - -    /*! -     * Get the RX gain range for the specified gain element. -     * For an empty name, calculate the overall gain range. -     * \param name the name of the gain element -     * \param chan the channel index 0 to N-1 -     * \return a gain range object -     */ -    virtual gain_range_t get_rx_gain_range(const std::string &name, size_t chan = 0) = 0; - -    //! A convenience wrapper for getting overall RX gain range -    gain_range_t get_rx_gain_range(size_t chan = 0){ -        return this->get_rx_gain_range(ALL_GAINS, chan); -    } - -    /*! -     * Get the names of the gain elements in the RX chain. -     * Gain elements are ordered from antenna to FPGA. -     * \param chan the channel index 0 to N-1 -     * \return a vector of gain element names -     */ -    virtual std::vector<std::string> get_rx_gain_names(size_t chan = 0) = 0; - -    /*! -     * Select the RX antenna on the subdevice. -     * \param ant the antenna name -     * \param chan the channel index 0 to N-1 -     */ -    virtual void set_rx_antenna(const std::string &ant, size_t chan = 0) = 0; - -    /*! -     * Get the selected RX antenna on the subdevice. -     * \param chan the channel index 0 to N-1 -     * \return the antenna name -     */ -    virtual std::string get_rx_antenna(size_t chan = 0) = 0; - -    /*! -     * Get a list of possible RX antennas on the subdevice. -     * \param chan the channel index 0 to N-1 -     * \return a vector of antenna names -     */ -    virtual std::vector<std::string> get_rx_antennas(size_t chan = 0) = 0; - -    /*! -     * Get the locked status of the LO on the subdevice. -     * \param chan the channel index 0 to N-1 -     * \return true for locked -     */ -    virtual bool get_rx_lo_locked(size_t chan = 0) = 0; - -    /*! -     * Set the RX bandwidth on the subdevice. -     * \param bandwidth the bandwidth in Hz -     * \param chan the channel index 0 to N-1 -     */ -    virtual void set_rx_bandwidth(double bandwidth, size_t chan = 0) = 0; - -    /*! -     * Get the RX bandwidth on the subdevice. -     * \param chan the channel index 0 to N-1 -     * \return the bandwidth in Hz -     */ -    virtual double get_rx_bandwidth(size_t chan = 0) = 0; - -    /*! -     * Read the RSSI value on the RX subdevice. -     * \param chan the channel index 0 to N-1 -     * \return the rssi in dB -     * \throw exception if RSSI readback not supported -     */ -    virtual double read_rssi(size_t chan = 0) = 0; - -    /*! -     * Get the dboard interface object for the RX subdevice. -     * The dboard interface gives access to GPIOs, SPI, I2C, low-speed ADC and DAC. -     * Use at your own risk! -     * \param chan the channel index 0 to N-1 -     * \return the dboard interface sptr -     */ -    virtual dboard_iface::sptr get_rx_dboard_iface(size_t chan = 0) = 0; - -    /******************************************************************* -     * TX methods -     ******************************************************************/ -    /*! -     * Set the TX subdevice specification: -     * The subdev spec maps a physical part of a daughter-board to a channel number. -     * Set the subdev spec before calling into any methods with a channel number. -     * \param spec the new subdevice specification -     */ -    virtual void set_tx_subdev_spec(const uhd::usrp::subdev_spec_t &spec) = 0; - -    /*! -     * Get the TX subdevice specification. -     * \return the subdevice specification in use -     */ -    virtual uhd::usrp::subdev_spec_t get_tx_subdev_spec(void) = 0; - -    /*! -     * Get the name of the TX subdevice. -     * \param chan the channel index 0 to N-1 -     * \return the subdevice name -     */ -    virtual std::string get_tx_subdev_name(size_t chan = 0) = 0; - -    /*! -     * Set the TX sample rate across all channels. -     * \param rate the rate in Sps -     */ -    virtual void set_tx_rate(double rate) = 0; - -    /*! -     * Gets the TX sample rate for all channels. -     * \return the rate in Sps -     */ -    virtual double get_tx_rate(void) = 0; - -    /*! -     * Set the TX center frequency. -     * \param tune_request tune request instructions -     * \param chan the channel index 0 to N-1 -     * \return a tune result object -     */ -    virtual tune_result_t set_tx_freq( -        const tune_request_t &tune_request, size_t chan = 0 -    ) = 0; - -    /*! -     * Get the TX center frequency. -     * \param chan the channel index 0 to N-1 -     * \return the frequency in Hz -     */ -    virtual double get_tx_freq(size_t chan = 0) = 0; - -    /*! -     * Get the TX center frequency range. -     * \param chan the channel index 0 to N-1 -     * \return a frequency range object -     */ -    virtual freq_range_t get_tx_freq_range(size_t chan = 0) = 0; - -    /*! -     * Set the TX gain value for the specified gain element. -     * For an empty name, distribute across all gain elements. -     * \param gain the gain in dB -     * \param name the name of the gain element -     * \param chan the channel index 0 to N-1 -     */ -    virtual void set_tx_gain(double gain, const std::string &name, size_t chan = 0) = 0; - -    //! A convenience wrapper for setting overall TX gain -    void set_tx_gain(double gain, size_t chan = 0){ -        return this->set_tx_gain(gain, ALL_GAINS, chan); -    } - -    /*! -     * Get the TX gain value for the specified gain element. -     * For an empty name, sum across all gain elements. -     * \param name the name of the gain element -     * \param chan the channel index 0 to N-1 -     * \return the gain in dB -     */ -    virtual double get_tx_gain(const std::string &name, size_t chan = 0) = 0; - -    //! A convenience wrapper for getting overall TX gain -    double get_tx_gain(size_t chan = 0){ -        return this->get_tx_gain(ALL_GAINS, chan); -    } - -    /*! -     * Get the TX gain range for the specified gain element. -     * For an empty name, calculate the overall gain range. -     * \param name the name of the gain element -     * \param chan the channel index 0 to N-1 -     * \return a gain range object -     */ -    virtual gain_range_t get_tx_gain_range(const std::string &name, size_t chan = 0) = 0; - -    //! A convenience wrapper for getting overall TX gain range -    gain_range_t get_tx_gain_range(size_t chan = 0){ -        return this->get_tx_gain_range(ALL_GAINS, chan); -    } - -    /*! -     * Get the names of the gain elements in the TX chain. -     * Gain elements are ordered from antenna to FPGA. -     * \param chan the channel index 0 to N-1 -     * \return a vector of gain element names -     */ -    virtual std::vector<std::string> get_tx_gain_names(size_t chan = 0) = 0; - -    /*! -     * Select the TX antenna on the subdevice. -     * \param ant the antenna name -     * \param chan the channel index 0 to N-1 -     */ -    virtual void set_tx_antenna(const std::string &ant, size_t chan = 0) = 0; - -    /*! -     * Get the selected TX antenna on the subdevice. -     * \param chan the channel index 0 to N-1 -     * \return the antenna name -     */ -    virtual std::string get_tx_antenna(size_t chan = 0) = 0; - -    /*! -     * Get a list of possible TX antennas on the subdevice. -     * \param chan the channel index 0 to N-1 -     * \return a vector of antenna names -     */ -    virtual std::vector<std::string> get_tx_antennas(size_t chan = 0) = 0; - -    /*! -     * Get the locked status of the LO on the subdevice. -     * \param chan the channel index 0 to N-1 -     * \return true for locked -     */ -    virtual bool get_tx_lo_locked(size_t chan = 0) = 0; - -    /*! -     * Set the TX bandwidth on the subdevice. -     * \param bandwidth the bandwidth in Hz -     * \param chan the channel index 0 to N-1 -     */ -    virtual void set_tx_bandwidth(double bandwidth, size_t chan = 0) = 0; - -    /*! -     * Get the TX bandwidth on the subdevice. -     * \param chan the channel index 0 to N-1 -     * \return the bandwidth in Hz -     */ -    virtual double get_tx_bandwidth(size_t chan = 0) = 0; - -    /*! -     * Get the dboard interface object for the TX subdevice. -     * The dboard interface gives access to GPIOs, SPI, I2C, low-speed ADC and DAC. -     * Use at your own risk! -     * \param chan the channel index 0 to N-1 -     * \return the dboard interface sptr -     */ -    virtual dboard_iface::sptr get_tx_dboard_iface(size_t chan = 0) = 0; -}; +    //! Multi-USRP is a superset of Single-USRP +    typedef multi_usrp single_usrp;  }} diff --git a/host/lib/transport/if_addrs.cpp b/host/lib/transport/if_addrs.cpp index ad9a2325b..17cf8455b 100644 --- a/host/lib/transport/if_addrs.cpp +++ b/host/lib/transport/if_addrs.cpp @@ -42,6 +42,7 @@ std::vector<uhd::transport::if_addrs_t> uhd::transport::get_if_addrs(void){      if (getifaddrs(&ifap) == 0){          for (struct ifaddrs *iter = ifap; iter != NULL; iter = iter->ifa_next){              //ensure that the entries are valid +            if (iter->ifa_addr == NULL) continue;              if (iter->ifa_addr->sa_family != AF_INET) continue;              if (iter->ifa_netmask->sa_family != AF_INET) continue;              if (iter->ifa_broadaddr->sa_family != AF_INET) continue; diff --git a/host/lib/transport/udp_zero_copy_asio.cpp b/host/lib/transport/udp_zero_copy_asio.cpp index 5c049cfad..697e172cd 100644 --- a/host/lib/transport/udp_zero_copy_asio.cpp +++ b/host/lib/transport/udp_zero_copy_asio.cpp @@ -24,7 +24,7 @@  #include <uhd/utils/warning.hpp>  #include <boost/asio.hpp>  #include <boost/format.hpp> -#include <boost/thread.hpp> +#include <boost/thread/thread.hpp>  #include <boost/enable_shared_from_this.hpp>  #include <iostream> @@ -32,9 +32,6 @@ using namespace uhd;  using namespace uhd::transport;  namespace asio = boost::asio; -/*********************************************************************** - * Constants - **********************************************************************/  //Define this to the the boost async io calls to perform receive.  //Otherwise, get_recv_buff uses a blocking receive with timeout.  #define USE_ASIO_ASYNC_RECV @@ -43,32 +40,6 @@ namespace asio = boost::asio;  //Otherwise, the commit callback uses a blocking send.  //#define USE_ASIO_ASYNC_SEND -//By default, this buffer is sized insufficiently small. -//For peformance, this buffer should be 10s of megabytes. -static const size_t MIN_RECV_SOCK_BUFF_SIZE = size_t(10e3); - -//Large buffers cause more underflow at high rates. -//Perhaps this is due to the kernel scheduling, -//but may change with host-based flow control. -static const size_t MIN_SEND_SOCK_BUFF_SIZE = size_t(10e3); - -//The number of async frames to allocate for each send and recv: -//The non-async recv can have a very large number of recv frames -//because the CPU overhead is independent of the number of frames. -#ifdef USE_ASIO_ASYNC_RECV -static const size_t DEFAULT_NUM_RECV_FRAMES = 32; -#else -static const size_t DEFAULT_NUM_RECV_FRAMES = MIN_RECV_SOCK_BUFF_SIZE/udp_simple::mtu; -#endif - -//The non-async send only ever requires a single frame -//because the buffer will be committed before a new get. -#ifdef USE_ASIO_ASYNC_SEND -static const size_t DEFAULT_NUM_SEND_FRAMES = 32; -#else -static const size_t DEFAULT_NUM_SEND_FRAMES = MIN_SEND_SOCK_BUFF_SIZE/udp_simple::mtu; -#endif -  //The number of service threads to spawn for async ASIO:  //A single concurrent thread for io_service seems to be the fastest.  //Threads are disabled when no async implementations are enabled. @@ -78,6 +49,9 @@ static const size_t CONCURRENCY_HINT = 1;  static const size_t CONCURRENCY_HINT = 0;  #endif +//A reasonable number of frames for send/recv and async/sync +static const size_t DEFAULT_NUM_FRAMES = 32; +  /***********************************************************************   * Zero Copy UDP implementation with ASIO:   *   This is the portable zero copy implementation for systems @@ -95,9 +69,9 @@ public:          const device_addr_t &hints      ):          _recv_frame_size(size_t(hints.cast<double>("recv_frame_size", udp_simple::mtu))), -        _num_recv_frames(size_t(hints.cast<double>("num_recv_frames", DEFAULT_NUM_RECV_FRAMES))), +        _num_recv_frames(size_t(hints.cast<double>("num_recv_frames", DEFAULT_NUM_FRAMES))),          _send_frame_size(size_t(hints.cast<double>("send_frame_size", udp_simple::mtu))), -        _num_send_frames(size_t(hints.cast<double>("num_send_frames", DEFAULT_NUM_SEND_FRAMES))), +        _num_send_frames(size_t(hints.cast<double>("num_send_frames", DEFAULT_NUM_FRAMES))),          _concurrency_hint(hints.cast<size_t>("concurrency_hint", CONCURRENCY_HINT)),          _io_service(_concurrency_hint)      { @@ -325,16 +299,11 @@ template<typename Opt> static void resize_buff_helper(      const size_t target_size,      const std::string &name  ){ -    size_t min_sock_buff_size = 0; -    if (name == "recv") min_sock_buff_size = MIN_RECV_SOCK_BUFF_SIZE; -    if (name == "send") min_sock_buff_size = MIN_SEND_SOCK_BUFF_SIZE; -    min_sock_buff_size = std::max(min_sock_buff_size, target_size); -      std::string help_message;      #if defined(UHD_PLATFORM_LINUX)          help_message = str(boost::format(              "Please run: sudo sysctl -w net.core.%smem_max=%d\n" -        ) % ((name == "recv")?"r":"w") % min_sock_buff_size); +        ) % ((name == "recv")?"r":"w") % target_size);      #endif /*defined(UHD_PLATFORM_LINUX)*/      //resize the buffer if size was provided @@ -348,19 +317,10 @@ template<typename Opt> static void resize_buff_helper(              "Current %s sock buff size: %d bytes"          ) % name % actual_size << std::endl;          if (actual_size < target_size) uhd::warning::post(str(boost::format( -            "The %s buffer is smaller than the requested size.\n" -            "The minimum requested buffer size is %d bytes.\n" +            "The %s buffer could not be resized sufficiently.\n"              "See the transport application notes on buffer resizing.\n%s" -        ) % name % min_sock_buff_size % help_message)); -    } - -    //only enable on platforms that are happy with the large buffer resize -    #if defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32) -    //otherwise, ensure that the buffer is at least the minimum size -    else if (udp_trans->get_buff_size<Opt>() < min_sock_buff_size){ -        resize_buff_helper<Opt>(udp_trans, min_sock_buff_size, name); +        ) % name % help_message));      } -    #endif /*defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32)*/  }  udp_zero_copy::sptr udp_zero_copy::make( diff --git a/host/lib/usrp/CMakeLists.txt b/host/lib/usrp/CMakeLists.txt index bd25aec2b..97a54a798 100644 --- a/host/lib/usrp/CMakeLists.txt +++ b/host/lib/usrp/CMakeLists.txt @@ -29,7 +29,6 @@ LIBUHD_APPEND_SOURCES(      ${CMAKE_CURRENT_SOURCE_DIR}/mboard_eeprom.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/misc_utils.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/multi_usrp.cpp -    ${CMAKE_CURRENT_SOURCE_DIR}/single_usrp.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/subdev_spec.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/tune_helper.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/wrapper_utils.hpp diff --git a/host/lib/usrp/gps_ctrl.cpp b/host/lib/usrp/gps_ctrl.cpp index 3c7c00134..b1062fa39 100644 --- a/host/lib/usrp/gps_ctrl.cpp +++ b/host/lib/usrp/gps_ctrl.cpp @@ -58,7 +58,7 @@ public:        if(trim_right_copy(reply) == "Command Error") {          gps_type = GPS_TYPE_JACKSON_LABS;          break; -      } +      }         else if(reply.substr(0, 3) == "$GP") i_heard_some_nmea = true; //but keep looking for that "Command Error" response        else if(reply.length() != 0) i_heard_something_weird = true; //probably wrong baud rate        boost::this_thread::sleep(boost::posix_time::milliseconds(200)); @@ -104,6 +104,7 @@ public:            found_gprmc = true;            break;          } +        boost::this_thread::sleep(boost::posix_time::milliseconds(200));        }        if(!found_gprmc) {          if(gps_type == GPS_TYPE_JACKSON_LABS) std::cout << "Firefly GPS not locked or warming up." << std::endl; @@ -127,16 +128,7 @@ public:  //TODO: this isn't generalizeable to non-USRP2 USRPs.    std::string safe_gps_read() { -    std::string reply; -    try { -        reply = _recv(); -    } catch (std::runtime_error err) { -      if(err.what() != std::string("usrp2 no control response")) throw; //sorry can't cope with that -      else { //we don't actually have a GPS installed -        reply = std::string(); -      } -    } -    return reply; +    return _recv();    }    ptime get_time(void) { @@ -196,7 +188,7 @@ private:      GPS_TYPE_NONE    } gps_type; -  static const int GPS_TIMEOUT_TRIES = 5; +  static const int GPS_TIMEOUT_TRIES = 10;    static const int GPS_TIMEOUT_DELAY_MS = 200;    static const int FIREFLY_STUPID_DELAY_MS = 200; diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp index 48eec28c1..817d7b085 100644 --- a/host/lib/usrp/multi_usrp.cpp +++ b/host/lib/usrp/multi_usrp.cpp @@ -53,11 +53,26 @@ public:      /*******************************************************************       * Mboard methods       ******************************************************************/ +    void set_master_clock_rate(double rate, size_t mboard){ +        if (mboard != ALL_MBOARDS){ +            _mboard(mboard)[MBOARD_PROP_CLOCK_RATE] = rate; +            return; +        } +        for (size_t m = 0; m < get_num_mboards(); m++){ +            set_master_clock_rate(rate, m); +        } +    } + +    double get_master_clock_rate(size_t mboard){ +        return _mboard(mboard)[MBOARD_PROP_CLOCK_RATE].as<double>(); +    } +      std::string get_pp_string(void){          std::string buff = str(boost::format( -            "Multi USRP:\n" +            "%s USRP:\n"              "  Device: %s\n"          ) +            % ((get_num_mboards() > 1)? "Multi" : "Single")              % (*_dev)[DEVICE_PROP_NAME].as<std::string>()          );          for (size_t m = 0; m < get_num_mboards(); m++){ @@ -121,6 +136,16 @@ public:          return _mboard(0)[MBOARD_PROP_TIME_PPS].as<time_spec_t>();      } +    void set_time_now(const time_spec_t &time_spec, size_t mboard){ +        if (mboard != ALL_MBOARDS){ +            _mboard(mboard)[MBOARD_PROP_TIME_NOW] = time_spec; +            return; +        } +        for (size_t m = 0; m < get_num_mboards(); m++){ +            set_time_now(time_spec, m); +        } +    } +      void set_time_next_pps(const time_spec_t &time_spec){          for (size_t m = 0; m < get_num_mboards(); m++){              _mboard(m)[MBOARD_PROP_TIME_PPS] = time_spec; diff --git a/host/lib/usrp/single_usrp.cpp b/host/lib/usrp/single_usrp.cpp deleted file mode 100644 index c37449c5f..000000000 --- a/host/lib/usrp/single_usrp.cpp +++ /dev/null @@ -1,339 +0,0 @@ -// -// Copyright 2010-2011 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/>. -// - -#include "wrapper_utils.hpp" -#include <uhd/usrp/single_usrp.hpp> -#include <uhd/usrp/tune_helper.hpp> -#include <uhd/utils/assert.hpp> -#include <uhd/utils/gain_group.hpp> -#include <uhd/usrp/subdev_props.hpp> -#include <uhd/usrp/mboard_props.hpp> -#include <uhd/usrp/device_props.hpp> -#include <uhd/usrp/dboard_props.hpp> -#include <uhd/usrp/dsp_props.hpp> -#include <boost/foreach.hpp> -#include <boost/format.hpp> -#include <stdexcept> -#include <iostream> - -using namespace uhd; -using namespace uhd::usrp; - -const std::string single_usrp::ALL_GAINS = ""; - -/*********************************************************************** - * Simple USRP Implementation - **********************************************************************/ -class single_usrp_impl : public single_usrp{ -public: -    single_usrp_impl(const device_addr_t &addr){ -        _dev = device::make(addr); -    } - -    device::sptr get_device(void){ -        return _dev; -    } - -    /******************************************************************* -     * Mboard methods -     ******************************************************************/ -    std::string get_pp_string(void){ -        std::string buff = str(boost::format( -            "Single USRP:\n" -            "  Device: %s\n" -            "  Mboard: %s\n" -        ) -            % (*_dev)[DEVICE_PROP_NAME].as<std::string>() -            % _mboard()[MBOARD_PROP_NAME].as<std::string>() -        ); - -        //----------- rx side of life ---------------------------------- -        buff += str(boost::format( -            "  RX DSP: %s\n" -        ) -            % _rx_dsp()[DSP_PROP_NAME].as<std::string>() -        ); -        for (size_t chan = 0; chan < this->get_rx_subdev_spec().size(); chan++){ -            buff += str(boost::format( -                "  RX Channel: %u\n" -                "    RX Dboard: %s\n" -                "    RX Subdev: %s\n" -            ) % chan -                % _rx_dboard(chan)[DBOARD_PROP_NAME].as<std::string>() -                % _rx_subdev(chan)[SUBDEV_PROP_NAME].as<std::string>() -            ); -        } - -        //----------- tx side of life ---------------------------------- -        buff += str(boost::format( -            "  TX DSP: %s\n" -        ) -            % _tx_dsp()[DSP_PROP_NAME].as<std::string>() -        ); -        for (size_t chan = 0; chan < this->get_tx_subdev_spec().size(); chan++){ -            buff += str(boost::format( -                "  TX Channel: %u\n" -                "    TX Dboard: %s\n" -                "    TX Subdev: %s\n" -            ) % chan -                % _tx_dboard(chan)[DBOARD_PROP_NAME].as<std::string>() -                % _tx_subdev(chan)[SUBDEV_PROP_NAME].as<std::string>() -            ); -        } - -        return buff; -    } - -    std::string get_mboard_name(void){ -        return _mboard()[MBOARD_PROP_NAME].as<std::string>(); -    } - -    time_spec_t get_time_now(void){ -        return _mboard()[MBOARD_PROP_TIME_NOW].as<time_spec_t>(); -    } - -    time_spec_t get_time_last_pps(void){ -        return _mboard()[MBOARD_PROP_TIME_PPS].as<time_spec_t>(); -    } - -    void set_time_now(const time_spec_t &time_spec){ -        _mboard()[MBOARD_PROP_TIME_NOW] = time_spec; -    } - -    void set_time_next_pps(const time_spec_t &time_spec){ -        _mboard()[MBOARD_PROP_TIME_PPS] = time_spec; -    } - -    void issue_stream_cmd(const stream_cmd_t &stream_cmd){ -        _mboard()[MBOARD_PROP_STREAM_CMD] = stream_cmd; -    } - -    void set_clock_config(const clock_config_t &clock_config){ -        _mboard()[MBOARD_PROP_CLOCK_CONFIG] = clock_config; -    } - -    /******************************************************************* -     * RX methods -     ******************************************************************/ -    void set_rx_subdev_spec(const subdev_spec_t &spec){ -        _mboard()[MBOARD_PROP_RX_SUBDEV_SPEC] = spec; -    } - -    subdev_spec_t get_rx_subdev_spec(void){ -        return _mboard()[MBOARD_PROP_RX_SUBDEV_SPEC].as<subdev_spec_t>(); -    } - -    std::string get_rx_subdev_name(size_t chan){ -        return _rx_subdev(chan)[SUBDEV_PROP_NAME].as<std::string>(); -    } - -    void set_rx_rate(double rate){ -        _rx_dsp()[DSP_PROP_HOST_RATE] = rate; -        do_samp_rate_warning_message(rate, get_rx_rate(), "RX"); -    } - -    double get_rx_rate(void){ -        return _rx_dsp()[DSP_PROP_HOST_RATE].as<double>(); -    } - -    tune_result_t set_rx_freq(const tune_request_t &tune_request, size_t chan){ -        tune_result_t r = tune_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(), chan, tune_request); -        do_tune_freq_warning_message(tune_request.target_freq, get_rx_freq(chan), "RX"); -        return r; -    } - -    double get_rx_freq(size_t chan){ -        return derive_freq_from_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(), chan); -    } - -    freq_range_t get_rx_freq_range(size_t chan){ -        return add_dsp_shift(_rx_subdev(chan)[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _rx_dsp()); -    } - -    void set_rx_gain(double gain, const std::string &name, size_t chan){ -        return _rx_gain_group(chan)->set_value(gain, name); -    } - -    double get_rx_gain(const std::string &name, size_t chan){ -        return _rx_gain_group(chan)->get_value(name); -    } - -    gain_range_t get_rx_gain_range(const std::string &name, size_t chan){ -        return _rx_gain_group(chan)->get_range(name); -    } - -    std::vector<std::string> get_rx_gain_names(size_t chan){ -        return _rx_gain_group(chan)->get_names(); -    } - -    void set_rx_antenna(const std::string &ant, size_t chan){ -        _rx_subdev(chan)[SUBDEV_PROP_ANTENNA] = ant; -    } - -    std::string get_rx_antenna(size_t chan){ -        return _rx_subdev(chan)[SUBDEV_PROP_ANTENNA].as<std::string>(); -    } - -    std::vector<std::string> get_rx_antennas(size_t chan){ -        return _rx_subdev(chan)[SUBDEV_PROP_ANTENNA_NAMES].as<prop_names_t>(); -    } - -    bool get_rx_lo_locked(size_t chan){ -        return _rx_subdev(chan)[SUBDEV_PROP_LO_LOCKED].as<bool>(); -    } - -    void set_rx_bandwidth(double bandwidth, size_t chan){ -        _rx_subdev(chan)[SUBDEV_PROP_BANDWIDTH] = bandwidth; -    } - -    double get_rx_bandwidth(size_t chan){ -        return _rx_subdev(chan)[SUBDEV_PROP_BANDWIDTH].as<double>(); -    } - -    double read_rssi(size_t chan){ -        return _rx_subdev(chan)[SUBDEV_PROP_RSSI].as<double>(); -    } - -    dboard_iface::sptr get_rx_dboard_iface(size_t chan){ -        return _rx_dboard(chan)[DBOARD_PROP_DBOARD_IFACE].as<dboard_iface::sptr>(); -    } - -    /******************************************************************* -     * TX methods -     ******************************************************************/ -    void set_tx_subdev_spec(const subdev_spec_t &spec){ -        _mboard()[MBOARD_PROP_TX_SUBDEV_SPEC] = spec; -    } - -    subdev_spec_t get_tx_subdev_spec(void){ -        return _mboard()[MBOARD_PROP_TX_SUBDEV_SPEC].as<subdev_spec_t>(); -    } - -    std::string get_tx_subdev_name(size_t chan){ -        return _tx_subdev(chan)[SUBDEV_PROP_NAME].as<std::string>(); -    } - -    void set_tx_rate(double rate){ -        _tx_dsp()[DSP_PROP_HOST_RATE] = rate; -        do_samp_rate_warning_message(rate, get_tx_rate(), "TX"); -    } - -    double get_tx_rate(void){ -        return _tx_dsp()[DSP_PROP_HOST_RATE].as<double>(); -    } - -    tune_result_t set_tx_freq(const tune_request_t &tune_request, size_t chan){ -        tune_result_t r = tune_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(), chan, tune_request); -        do_tune_freq_warning_message(tune_request.target_freq, get_tx_freq(chan), "TX"); -        return r; -    } - -    double get_tx_freq(size_t chan){ -        return derive_freq_from_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(), chan); -    } - -    freq_range_t get_tx_freq_range(size_t chan){ -        return add_dsp_shift(_tx_subdev(chan)[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _tx_dsp()); -    } - -    void set_tx_gain(double gain, const std::string &name, size_t chan){ -        return _tx_gain_group(chan)->set_value(gain, name); -    } - -    double get_tx_gain(const std::string &name, size_t chan){ -        return _tx_gain_group(chan)->get_value(name); -    } - -    gain_range_t get_tx_gain_range(const std::string &name, size_t chan){ -        return _tx_gain_group(chan)->get_range(name); -    } - -    std::vector<std::string> get_tx_gain_names(size_t chan){ -        return _tx_gain_group(chan)->get_names(); -    } - -    void set_tx_antenna(const std::string &ant, size_t chan){ -        _tx_subdev(chan)[SUBDEV_PROP_ANTENNA] = ant; -    } - -    std::string get_tx_antenna(size_t chan){ -        return _tx_subdev(chan)[SUBDEV_PROP_ANTENNA].as<std::string>(); -    } - -    std::vector<std::string> get_tx_antennas(size_t chan){ -        return _tx_subdev(chan)[SUBDEV_PROP_ANTENNA_NAMES].as<prop_names_t>(); -    } - -    bool get_tx_lo_locked(size_t chan){ -        return _tx_subdev(chan)[SUBDEV_PROP_LO_LOCKED].as<bool>(); -    } - -    void set_tx_bandwidth(double bandwidth, size_t chan){ -        _tx_subdev(chan)[SUBDEV_PROP_BANDWIDTH] = bandwidth; -    } - -    double get_tx_bandwidth(size_t chan){ -        return _tx_subdev(chan)[SUBDEV_PROP_BANDWIDTH].as<double>(); -    } - -    dboard_iface::sptr get_tx_dboard_iface(size_t chan){ -        return _tx_dboard(chan)[DBOARD_PROP_DBOARD_IFACE].as<dboard_iface::sptr>(); -    } - -private: -    device::sptr _dev; -    wax::obj _mboard(void){ -        return (*_dev)[DEVICE_PROP_MBOARD]; -    } -    wax::obj _rx_dsp(void){ -        return _mboard()[MBOARD_PROP_RX_DSP]; -    } -    wax::obj _tx_dsp(void){ -        return _mboard()[MBOARD_PROP_TX_DSP]; -    } -    wax::obj _rx_dboard(size_t chan){ -        std::string db_name = this->get_rx_subdev_spec().at(chan).db_name; -        return _mboard()[named_prop_t(MBOARD_PROP_RX_DBOARD, db_name)]; -    } -    wax::obj _tx_dboard(size_t chan){ -        std::string db_name = this->get_tx_subdev_spec().at(chan).db_name; -        return _mboard()[named_prop_t(MBOARD_PROP_TX_DBOARD, db_name)]; -    } -    wax::obj _rx_subdev(size_t chan){ -        std::string sd_name = this->get_rx_subdev_spec().at(chan).sd_name; -        return _rx_dboard(chan)[named_prop_t(DBOARD_PROP_SUBDEV, sd_name)]; -    } -    wax::obj _tx_subdev(size_t chan){ -        std::string sd_name = this->get_tx_subdev_spec().at(chan).sd_name; -        return _tx_dboard(chan)[named_prop_t(DBOARD_PROP_SUBDEV, sd_name)]; -    } -    gain_group::sptr _rx_gain_group(size_t chan){ -        std::string sd_name = this->get_rx_subdev_spec().at(chan).sd_name; -        return _rx_dboard(chan)[named_prop_t(DBOARD_PROP_GAIN_GROUP, sd_name)].as<gain_group::sptr>(); -    } -    gain_group::sptr _tx_gain_group(size_t chan){ -        std::string sd_name = this->get_tx_subdev_spec().at(chan).sd_name; -        return _tx_dboard(chan)[named_prop_t(DBOARD_PROP_GAIN_GROUP, sd_name)].as<gain_group::sptr>(); -    } -}; - -/*********************************************************************** - * The Make Function - **********************************************************************/ -single_usrp::sptr single_usrp::make(const device_addr_t &dev_addr){ -    return sptr(new single_usrp_impl(dev_addr)); -} diff --git a/host/lib/usrp/subdev_spec.cpp b/host/lib/usrp/subdev_spec.cpp index 51c88bda3..d5d950f1f 100644 --- a/host/lib/usrp/subdev_spec.cpp +++ b/host/lib/usrp/subdev_spec.cpp @@ -46,7 +46,7 @@ bool usrp::operator==(const subdev_spec_pair_t &lhs, const subdev_spec_pair_t &r  subdev_spec_t::subdev_spec_t(const std::string &markup){      BOOST_FOREACH(const std::string &pair, pair_tokenizer(markup)){ -        if (pair == "") continue; +        if (pair.empty()) continue;          std::vector<std::string> db_sd; boost::split(db_sd, pair, boost::is_any_of(":"));          switch(db_sd.size()){          case 1: this->push_back(subdev_spec_pair_t("", db_sd.front())); break; diff --git a/host/lib/usrp/usrp1/clock_ctrl.cpp b/host/lib/usrp/usrp1/clock_ctrl.cpp index 68c5f5320..156f2b0c4 100644 --- a/host/lib/usrp/usrp1/clock_ctrl.cpp +++ b/host/lib/usrp/usrp1/clock_ctrl.cpp @@ -29,32 +29,33 @@ using namespace uhd;  /***********************************************************************   * Constants   **********************************************************************/ -static const double master_clock_rate = 64e6; +static const double default_master_clock_rate = 64e6;  /***********************************************************************   * Clock Control Implementation   **********************************************************************/  class usrp1_clock_ctrl_impl : public usrp1_clock_ctrl {  public: -    usrp1_clock_ctrl_impl(usrp1_iface::sptr iface) -    { -        _iface = iface; +    usrp1_clock_ctrl_impl(usrp1_iface::sptr iface): _iface(iface){ +        this->set_master_clock_freq(default_master_clock_rate);      } -    double get_master_clock_freq(void) -    { -        return master_clock_rate;  +    void set_master_clock_freq(double freq){ +        _freq = freq; +    } + +    double get_master_clock_freq(void){ +        return _freq;      }  private:      usrp1_iface::sptr _iface; - +    double _freq;  };  /***********************************************************************   * Clock Control Make   **********************************************************************/ -usrp1_clock_ctrl::sptr usrp1_clock_ctrl::make(usrp1_iface::sptr iface) -{ +usrp1_clock_ctrl::sptr usrp1_clock_ctrl::make(usrp1_iface::sptr iface){      return sptr(new usrp1_clock_ctrl_impl(iface));  } diff --git a/host/lib/usrp/usrp1/clock_ctrl.hpp b/host/lib/usrp/usrp1/clock_ctrl.hpp index 366869dab..645472f02 100644 --- a/host/lib/usrp/usrp1/clock_ctrl.hpp +++ b/host/lib/usrp/usrp1/clock_ctrl.hpp @@ -40,6 +40,13 @@ public:      static sptr make(usrp1_iface::sptr iface);      /*! +     * Set the rate of the fpga clock line. +     * Note: does not really set, its all software. +     * \param freq the new clock rate in Hz +     */ +    virtual void set_master_clock_freq(double freq) = 0; + +    /*!       * Get the rate of the fpga clock line.       * \return the fpga clock rate in Hz       */ diff --git a/host/lib/usrp/usrp1/mboard_impl.cpp b/host/lib/usrp/usrp1/mboard_impl.cpp index 23c8f03c4..6d5bf466d 100644 --- a/host/lib/usrp/usrp1/mboard_impl.cpp +++ b/host/lib/usrp/usrp1/mboard_impl.cpp @@ -317,6 +317,10 @@ void usrp1_impl::mboard_get(const wax::obj &key_, wax::obj &val)          val = _soft_time_ctrl->get_time();          return; +    case MBOARD_PROP_CLOCK_RATE: +        val = _clock_ctrl->get_master_clock_freq(); +        return; +      default: UHD_THROW_PROP_GET_ERROR();      }  } @@ -379,6 +383,10 @@ void usrp1_impl::mboard_set(const wax::obj &key, const wax::obj &val)          _soft_time_ctrl->set_time(val.as<time_spec_t>());          return; +    case MBOARD_PROP_CLOCK_RATE: +        _clock_ctrl->set_master_clock_freq(val.as<double>()); +        return; +      default: UHD_THROW_PROP_SET_ERROR();      }  } diff --git a/host/lib/usrp/usrp1/soft_time_ctrl.cpp b/host/lib/usrp/usrp1/soft_time_ctrl.cpp index 856faf89d..c91ecc7ed 100644 --- a/host/lib/usrp/usrp1/soft_time_ctrl.cpp +++ b/host/lib/usrp/usrp1/soft_time_ctrl.cpp @@ -69,6 +69,9 @@ public:          _thread_group.create_thread(boost::bind(&soft_time_ctrl_impl::recv_cmd_dispatcher, this));          _update_mutex.lock(); //lock blocks until spawned          _update_mutex.unlock(); //unlock mutex before done + +        //initialize the time to something +        this->set_time(time_spec_t(0.0));      }      ~soft_time_ctrl_impl(void){ diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 95f7013e7..784f662d9 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -66,9 +66,9 @@ usrp2_mboard_impl::usrp2_mboard_impl(      //contruct the interfaces to mboard perifs      _clock_ctrl = usrp2_clock_ctrl::make(_iface);      _codec_ctrl = usrp2_codec_ctrl::make(_iface); -    //_gps_ctrl = gps_ctrl::make( -    //    _iface->get_gps_write_fn(), -    //    _iface->get_gps_read_fn()); +//    _gps_ctrl = gps_ctrl::make( +//        _iface->get_gps_write_fn(), +//        _iface->get_gps_read_fn());      //if(_gps_ctrl->gps_detected()) std::cout << "GPS time: " << _gps_ctrl->get_time() << std::endl; @@ -243,6 +243,9 @@ void usrp2_mboard_impl::update_clock_config(void){  }  void usrp2_mboard_impl::set_time_spec(const time_spec_t &time_spec, bool now){ +    //dont set the time for slave devices, they always take from mimo cable +    if (not _mimo_clocking_mode_is_master) return; +      //set the ticks      _iface->poke32(_iface->regs.time64_ticks, time_spec.get_tick_count(get_master_clock_freq())); @@ -352,6 +355,10 @@ void usrp2_mboard_impl::get(const wax::obj &key_, wax::obj &val){          val = _iface->mb_eeprom;          return; +    case MBOARD_PROP_CLOCK_RATE: +        val = this->get_master_clock_freq(); +        return; +      default: UHD_THROW_PROP_GET_ERROR();      }  } @@ -409,6 +416,10 @@ void usrp2_mboard_impl::set(const wax::obj &key, const wax::obj &val){          _iface->mb_eeprom = mboard_eeprom_t(*_iface, mboard_eeprom_t::MAP_N100);          return; +    case MBOARD_PROP_CLOCK_RATE: +        UHD_ASSERT_THROW(val.as<double>() == this->get_master_clock_freq()); +        return; +      default: UHD_THROW_PROP_SET_ERROR();      }  } diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 059ddf65f..9ce0f7359 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -202,8 +202,11 @@ static device::sptr usrp2_make(const device_addr_t &device_addr){      //setup the dsp transport hints (default to a large recv buff)      device_addr_t dsp_xport_hints = device_addr;      if (not dsp_xport_hints.has_key("recv_buff_size")){ -        //set to half-a-second of buffering at max rate -        dsp_xport_hints["recv_buff_size"] = "50e6"; +        //only enable on platforms that are happy with the large buffer resize +        #if defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32) +            //set to half-a-second of buffering at max rate +            dsp_xport_hints["recv_buff_size"] = "50e6"; +        #endif /*defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32)*/      }      //create a ctrl and data transport for each address diff --git a/host/lib/usrp/usrp_e100/usrp_e100_impl.hpp b/host/lib/usrp/usrp_e100/usrp_e100_impl.hpp index 864e82099..df8e5dc9f 100644 --- a/host/lib/usrp/usrp_e100/usrp_e100_impl.hpp +++ b/host/lib/usrp/usrp_e100/usrp_e100_impl.hpp @@ -30,7 +30,7 @@  #ifndef INCLUDED_USRP_E100_IMPL_HPP  #define INCLUDED_USRP_E100_IMPL_HPP -static const boost::uint16_t USRP_E_COMPAT_NUM = 0x03; +static const boost::uint16_t USRP_E_COMPAT_NUM = 0x02; //make this 3 then the mainline fpga image gets fixed for embedded  //! load an fpga image from a bin file into the usrp-e fpga  extern void usrp_e100_load_fpga(const std::string &bin_file); diff --git a/host/lib/utils/paths.cpp b/host/lib/utils/paths.cpp index 93d15d290..8d604d849 100644 --- a/host/lib/utils/paths.cpp +++ b/host/lib/utils/paths.cpp @@ -64,6 +64,7 @@ static std::vector<fs::path> get_env_paths(const std::string &var_name){      //convert to filesystem path, filter blank paths      std::vector<fs::path> paths; +    if (var_value.empty()) return paths; //FIXME boost tokenizer throws w/ blank strings on some platforms      BOOST_FOREACH(const std::string &path_string, path_tokenizer(var_value)){          if (path_string.empty()) continue;          paths.push_back(fs::system_complete(path_string)); | 
