diff options
| author | Josh Blum <josh@joshknows.com> | 2011-02-03 18:51:42 -0800 | 
|---|---|---|
| committer | Josh Blum <josh@joshknows.com> | 2011-02-03 18:51:42 -0800 | 
| commit | d6c52af6a8ac2e2a85942116768cf69971aac48a (patch) | |
| tree | 58f90b7da55eda0317ac1343ad7878c9adfdc631 | |
| parent | 5d459d1cb09cdce0c1fd4d7e7d0259310921b94f (diff) | |
| parent | 43b19815fec253dc7e5538329f9fe1363f007b8a (diff) | |
| download | uhd-d6c52af6a8ac2e2a85942116768cf69971aac48a.tar.gz uhd-d6c52af6a8ac2e2a85942116768cf69971aac48a.tar.bz2 uhd-d6c52af6a8ac2e2a85942116768cf69971aac48a.zip | |
Merge branch 'convert_fc64'
27 files changed, 376 insertions, 1138 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/examples/benchmark_rx_rate.cpp b/host/examples/benchmark_rx_rate.cpp index c993af970..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 @@ -94,14 +94,14 @@ static inline void test_device(          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; @@ -137,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/types/io_type.hpp b/host/include/uhd/types/io_type.hpp index 5176374d6..990d701f9 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,15 @@ namespace uhd{           * Built in IO types known to the system.           */          enum tid_t{ +            //! Custom type (technically unsupported by implementation)              CUSTOM_TYPE =     '?', +            //! Complex floating point (64-bit floats) range [-1.0, +1.0] +            COMPLEX_FLOAT64 = 'd', +            //! 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/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/convert/convert_common.hpp b/host/lib/convert/convert_common.hpp index 1a653a56f..c6ba1fcf9 100644 --- a/host/lib/convert/convert_common.hpp +++ b/host/lib/convert/convert_common.hpp @@ -41,8 +41,10 @@  /***********************************************************************   * Typedefs   **********************************************************************/ +typedef std::complex<double>         fc64_t;  typedef std::complex<float>          fc32_t;  typedef std::complex<boost::int16_t> sc16_t; +typedef std::complex<boost::int8_t>  sc8_t;  typedef boost::uint32_t              item32_t;  /*********************************************************************** @@ -87,4 +89,27 @@ static UHD_INLINE fc32_t item32_to_fc32(item32_t item){      );  } +/*********************************************************************** + * Convert complex double buffer to items32 (no swap) + **********************************************************************/ +static const double shorts_per_double = double(32767); + +static UHD_INLINE item32_t fc64_to_item32(fc64_t num){ +    boost::uint16_t real = boost::int16_t(num.real()*shorts_per_double); +    boost::uint16_t imag = boost::int16_t(num.imag()*shorts_per_double); +    return (item32_t(real) << 16) | (item32_t(imag) << 0); +} + +/*********************************************************************** + * Convert items32 buffer to complex double + **********************************************************************/ +static const double doubles_per_short = double(1.0/shorts_per_double); + +static UHD_INLINE fc64_t item32_to_fc64(item32_t item){ +    return fc64_t( +        float(boost::int16_t(item >> 16)*doubles_per_short), +        float(boost::int16_t(item >> 0)*doubles_per_short) +    ); +} +  #endif /* INCLUDED_LIBUHD_CONVERT_COMMON_HPP */ diff --git a/host/lib/convert/gen_convert_general.py b/host/lib/convert/gen_convert_general.py index 47c4cd7d0..f03448047 100644 --- a/host/lib/convert/gen_convert_general.py +++ b/host/lib/convert/gen_convert_general.py @@ -85,7 +85,7 @@ if __name__ == '__main__':      output = parse_tmpl(TMPL_HEADER, file=file)      for width in 1, 2, 3, 4:          for swap, swap_fcn in (('nswap', ''), ('bswap', 'uhd::byteswap')): -            for cpu_type in 'fc32', 'sc16': +            for cpu_type in 'fc64', 'fc32', 'sc16':                  output += parse_tmpl(                      TMPL_CONV_TO_FROM_ITEM32_1 if width == 1 else TMPL_CONV_TO_FROM_ITEM32_X,                      width=width, swap=swap, swap_fcn=swap_fcn, cpu_type=cpu_type diff --git a/host/lib/convert/gen_convert_pred.py b/host/lib/convert/gen_convert_pred.py index 1d573bf1a..fea7db4cc 100644 --- a/host/lib/convert/gen_convert_pred.py +++ b/host/lib/convert/gen_convert_pred.py @@ -69,8 +69,10 @@ pred_type make_pred(const std::string &markup, dir_type &dir){              dir = DIR_OTW_TO_CPU;          } -        if      (cpu_type == "fc32") pred |= $ph.fc32_p; +        if      (cpu_type == "fc64") pred |= $ph.fc64_p; +        else if (cpu_type == "fc32") pred |= $ph.fc32_p;          else if (cpu_type == "sc16") pred |= $ph.sc16_p; +        else if (cpu_type == "sc8")  pred |= $ph.sc8_p;          else throw pred_error("unhandled io type " + cpu_type);          if (otw_type == "item32") pred |= $ph.item32_p; @@ -127,6 +129,8 @@ UHD_INLINE pred_type make_pred(      switch(io_type.tid){      case io_type_t::COMPLEX_FLOAT32: pred |= $ph.fc32_p; break;      case io_type_t::COMPLEX_INT16:   pred |= $ph.sc16_p; break; +    //case io_type_t::COMPLEX_INT8:    pred |= $ph.sc8_p; break; +    case io_type_t::COMPLEX_FLOAT64: pred |= $ph.fc64_p; break;      default: throw pred_error("unhandled io type id");      } @@ -150,12 +154,14 @@ class ph:      bswap_p  = 0b00001      nswap_p  = 0b00000      item32_p = 0b00000 +    sc8_p    = 0b00000      sc16_p   = 0b00010 -    fc32_p   = 0b00000 +    fc32_p   = 0b00100 +    fc64_p   = 0b00110      chan1_p  = 0b00000 -    chan2_p  = 0b00100 -    chan3_p  = 0b01000 -    chan4_p  = 0b01100 +    chan2_p  = 0b01000 +    chan3_p  = 0b10000 +    chan4_p  = 0b11000  if __name__ == '__main__':      import sys, os diff --git a/host/lib/types/types.cpp b/host/lib/types/types.cpp index 34d5947eb..c1be2ff6d 100644 --- a/host/lib/types/types.cpp +++ b/host/lib/types/types.cpp @@ -68,6 +68,7 @@ otw_type_t::otw_type_t(void):   **********************************************************************/  static size_t tid_to_size(io_type_t::tid_t tid){      switch(tid){ +    case io_type_t::COMPLEX_FLOAT64: return sizeof(std::complex<double>);      case io_type_t::COMPLEX_FLOAT32: return sizeof(std::complex<float>);      case io_type_t::COMPLEX_INT16:   return sizeof(std::complex<boost::int16_t>);      case io_type_t::COMPLEX_INT8:    return sizeof(std::complex<boost::int8_t>); 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/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/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/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 3e7e8b01f..784f662d9 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -355,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();      }  } @@ -412,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/tests/convert_test.cpp b/host/tests/convert_test.cpp index 5f2aaf3d1..d3c235e9b 100644 --- a/host/tests/convert_test.cpp +++ b/host/tests/convert_test.cpp @@ -29,6 +29,7 @@ using namespace uhd;  //typedefs for complex types  typedef std::complex<boost::int16_t> sc16_t;  typedef std::complex<float> fc32_t; +typedef std::complex<double> fc64_t;  #define MY_CHECK_CLOSE(a, b, f) if ((std::abs(a) > (f) and std::abs(b) > (f))) \      BOOST_CHECK_CLOSE_FRACTION(a, b, f) @@ -109,23 +110,26 @@ BOOST_AUTO_TEST_CASE(test_convert_types_le_sc16){  /***********************************************************************   * Test float conversion   **********************************************************************/ -static void test_convert_types_fc32( +template <typename data_type> +static void test_convert_types_for_floats(      size_t nsamps,      const io_type_t &io_type,      const otw_type_t &otw_type  ){ +    typedef typename data_type::value_type value_type; +      //fill the input samples -    std::vector<fc32_t> input(nsamps), output(nsamps); -    BOOST_FOREACH(fc32_t &in, input) in = fc32_t( -        (std::rand()/float(RAND_MAX/2)) - 1, -        (std::rand()/float(RAND_MAX/2)) - 1 +    std::vector<data_type> input(nsamps), output(nsamps); +    BOOST_FOREACH(data_type &in, input) in = data_type( +        (std::rand()/value_type(RAND_MAX/2)) - 1, +        (std::rand()/value_type(RAND_MAX/2)) - 1      );      //run the loopback and test      loopback(nsamps, io_type, otw_type, input, output);      for (size_t i = 0; i < nsamps; i++){ -        MY_CHECK_CLOSE(input[i].real(), output[i].real(), float(0.01)); -        MY_CHECK_CLOSE(input[i].imag(), output[i].imag(), float(0.01)); +        MY_CHECK_CLOSE(input[i].real(), output[i].real(), value_type(0.01)); +        MY_CHECK_CLOSE(input[i].imag(), output[i].imag(), value_type(0.01));      }  } @@ -137,7 +141,7 @@ BOOST_AUTO_TEST_CASE(test_convert_types_be_fc32){      //try various lengths to test edge cases      for (size_t nsamps = 1; nsamps < 16; nsamps++){ -        test_convert_types_fc32(nsamps, io_type, otw_type); +        test_convert_types_for_floats<fc32_t>(nsamps, io_type, otw_type);      }  } @@ -149,7 +153,31 @@ BOOST_AUTO_TEST_CASE(test_convert_types_le_fc32){      //try various lengths to test edge cases      for (size_t nsamps = 1; nsamps < 16; nsamps++){ -        test_convert_types_fc32(nsamps, io_type, otw_type); +        test_convert_types_for_floats<fc32_t>(nsamps, io_type, otw_type); +    } +} + +BOOST_AUTO_TEST_CASE(test_convert_types_be_fc64){ +    io_type_t io_type(io_type_t::COMPLEX_FLOAT64); +    otw_type_t otw_type; +    otw_type.byteorder = otw_type_t::BO_BIG_ENDIAN; +    otw_type.width = 16; + +    //try various lengths to test edge cases +    for (size_t nsamps = 1; nsamps < 16; nsamps++){ +        test_convert_types_for_floats<fc64_t>(nsamps, io_type, otw_type); +    } +} + +BOOST_AUTO_TEST_CASE(test_convert_types_le_fc64){ +    io_type_t io_type(io_type_t::COMPLEX_FLOAT64); +    otw_type_t otw_type; +    otw_type.byteorder = otw_type_t::BO_LITTLE_ENDIAN; +    otw_type.width = 16; + +    //try various lengths to test edge cases +    for (size_t nsamps = 1; nsamps < 16; nsamps++){ +        test_convert_types_for_floats<fc64_t>(nsamps, io_type, otw_type);      }  } | 
