diff options
Diffstat (limited to 'host/lib/usrp')
61 files changed, 984 insertions, 1116 deletions
| diff --git a/host/lib/usrp/CMakeLists.txt b/host/lib/usrp/CMakeLists.txt index 97a54a798..59dabbd58 100644 --- a/host/lib/usrp/CMakeLists.txt +++ b/host/lib/usrp/CMakeLists.txt @@ -31,7 +31,6 @@ LIBUHD_APPEND_SOURCES(      ${CMAKE_CURRENT_SOURCE_DIR}/multi_usrp.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/subdev_spec.cpp      ${CMAKE_CURRENT_SOURCE_DIR}/tune_helper.cpp -    ${CMAKE_CURRENT_SOURCE_DIR}/wrapper_utils.hpp  )  INCLUDE_SUBDIRECTORY(dboard) diff --git a/host/lib/usrp/dboard/db_basic_and_lf.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp index b319289db..3fffeab0c 100644 --- a/host/lib/usrp/dboard/db_basic_and_lf.cpp +++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp @@ -18,7 +18,7 @@  #include <uhd/usrp/subdev_props.hpp>  #include <uhd/types/dict.hpp>  #include <uhd/types/ranges.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/utils/assert_has.hpp>  #include <uhd/utils/static.hpp>  #include <uhd/utils/warning.hpp>  #include <uhd/usrp/dboard_base.hpp> @@ -193,7 +193,7 @@ void basic_rx::rx_set(const wax::obj &key_, const wax::obj &val){      case SUBDEV_PROP_ANTENNA:          if (val.as<std::string>().empty()) return; -        throw std::runtime_error("no selectable antennas on this board"); +        throw uhd::value_error("no selectable antennas on this board");      case SUBDEV_PROP_FREQ:          return; // it wont do you much good, but you can set it @@ -300,7 +300,7 @@ void basic_tx::tx_set(const wax::obj &key_, const wax::obj &val){      case SUBDEV_PROP_ANTENNA:          if (val.as<std::string>().empty()) return; -        throw std::runtime_error("no selectable antennas on this board"); +        throw uhd::value_error("no selectable antennas on this board");      case SUBDEV_PROP_FREQ:          return; // it wont do you much good, but you can set it diff --git a/host/lib/usrp/dboard/db_dbsrx.cpp b/host/lib/usrp/dboard/db_dbsrx.cpp index 98d9479fc..b984608ca 100644 --- a/host/lib/usrp/dboard/db_dbsrx.cpp +++ b/host/lib/usrp/dboard/db_dbsrx.cpp @@ -21,7 +21,7 @@  #include "max2118_regs.hpp"  #include <uhd/utils/static.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/utils/assert_has.hpp>  #include <uhd/utils/algorithm.hpp>  #include <uhd/utils/warning.hpp>  #include <uhd/types/ranges.hpp> @@ -83,8 +83,8 @@ private:      void set_bandwidth(double bandwidth);      void send_reg(boost::uint8_t start_reg, boost::uint8_t stop_reg){ -        start_reg = boost::uint8_t(std::clip(int(start_reg), 0x0, 0x5)); -        stop_reg = boost::uint8_t(std::clip(int(stop_reg), 0x0, 0x5)); +        start_reg = boost::uint8_t(uhd::clip(int(start_reg), 0x0, 0x5)); +        stop_reg = boost::uint8_t(uhd::clip(int(stop_reg), 0x0, 0x5));          for(boost::uint8_t start_addr=start_reg; start_addr <= stop_reg; start_addr += sizeof(boost::uint32_t) - 1){              int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(boost::uint32_t)) - 1 ? sizeof(boost::uint32_t) - 1 : stop_reg - start_addr + 1; @@ -112,8 +112,8 @@ private:      void read_reg(boost::uint8_t start_reg, boost::uint8_t stop_reg){          static const boost::uint8_t status_addr = 0x0; -        start_reg = boost::uint8_t(std::clip(int(start_reg), 0x0, 0x1)); -        stop_reg = boost::uint8_t(std::clip(int(stop_reg), 0x0, 0x1)); +        start_reg = boost::uint8_t(uhd::clip(int(start_reg), 0x0, 0x1)); +        stop_reg = boost::uint8_t(uhd::clip(int(stop_reg), 0x0, 0x1));          for(boost::uint8_t start_addr=start_reg; start_addr <= stop_reg; start_addr += sizeof(boost::uint32_t)){              int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(boost::uint32_t)) ? sizeof(boost::uint32_t) : stop_reg - start_addr + 1; @@ -237,8 +237,8 @@ void dbsrx::set_lo_freq(double target_freq){      bool update_filter_settings = false;      //choose refclock      std::vector<double> clock_rates = this->get_iface()->get_clock_rates(dboard_iface::UNIT_RX); -    const double max_clock_rate = std::sorted(clock_rates).back(); -    BOOST_FOREACH(ref_clock, std::reversed(std::sorted(clock_rates))){ +    const double max_clock_rate = uhd::sorted(clock_rates).back(); +    BOOST_FOREACH(ref_clock, uhd::reversed(uhd::sorted(clock_rates))){          if (ref_clock > 27.0e6) continue;          if (size_t(max_clock_rate/ref_clock)%2 == 1) continue; //reject asymmetric clocks (odd divisors) @@ -485,14 +485,14 @@ void dbsrx::set_gain(double gain, const std::string &name){   **********************************************************************/  void dbsrx::set_bandwidth(double bandwidth){      //clip the input -    bandwidth = std::clip<double>(bandwidth, 4e6, 33e6); +    bandwidth = uhd::clip<double>(bandwidth, 4e6, 33e6);      double ref_clock = this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX);      //NOTE: _max2118_write_regs.m_divider set in set_lo_freq      //compute f_dac setting -    _max2118_write_regs.f_dac = std::clip<int>(int((((bandwidth*_max2118_write_regs.m_divider)/ref_clock) - 4)/0.145),0,127); +    _max2118_write_regs.f_dac = uhd::clip<int>(int((((bandwidth*_max2118_write_regs.m_divider)/ref_clock) - 4)/0.145),0,127);      //determine actual bandwidth      _bandwidth = double((ref_clock/(_max2118_write_regs.m_divider))*(4+0.145*_max2118_write_regs.f_dac)); diff --git a/host/lib/usrp/dboard/db_dbsrx2.cpp b/host/lib/usrp/dboard/db_dbsrx2.cpp index f4b797995..e7b42cb05 100644 --- a/host/lib/usrp/dboard/db_dbsrx2.cpp +++ b/host/lib/usrp/dboard/db_dbsrx2.cpp @@ -19,7 +19,7 @@  #include "max2112_regs.hpp"  #include <uhd/utils/static.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/utils/assert_has.hpp>  #include <uhd/utils/algorithm.hpp>  #include <uhd/types/ranges.hpp>  #include <uhd/types/sensors.hpp> @@ -79,8 +79,8 @@ private:      void set_bandwidth(double bandwidth);      void send_reg(boost::uint8_t start_reg, boost::uint8_t stop_reg){ -        start_reg = boost::uint8_t(std::clip(int(start_reg), 0x0, 0xB)); -        stop_reg = boost::uint8_t(std::clip(int(stop_reg), 0x0, 0xB)); +        start_reg = boost::uint8_t(uhd::clip(int(start_reg), 0x0, 0xB)); +        stop_reg = boost::uint8_t(uhd::clip(int(stop_reg), 0x0, 0xB));          for(boost::uint8_t start_addr=start_reg; start_addr <= stop_reg; start_addr += sizeof(boost::uint32_t) - 1){              int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(boost::uint32_t)) - 1 ? sizeof(boost::uint32_t) - 1 : stop_reg - start_addr + 1; @@ -108,8 +108,8 @@ private:      void read_reg(boost::uint8_t start_reg, boost::uint8_t stop_reg){          static const boost::uint8_t status_addr = 0xC; -        start_reg = boost::uint8_t(std::clip(int(start_reg), 0x0, 0xD)); -        stop_reg = boost::uint8_t(std::clip(int(stop_reg), 0x0, 0xD)); +        start_reg = boost::uint8_t(uhd::clip(int(start_reg), 0x0, 0xD)); +        stop_reg = boost::uint8_t(uhd::clip(int(stop_reg), 0x0, 0xD));          for(boost::uint8_t start_addr=start_reg; start_addr <= stop_reg; start_addr += sizeof(boost::uint32_t)){              int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(boost::uint32_t)) ? sizeof(boost::uint32_t) : stop_reg - start_addr + 1; @@ -216,7 +216,7 @@ dbsrx2::~dbsrx2(void){   * Tuning   **********************************************************************/  void dbsrx2::set_lo_freq(double target_freq){ -    //target_freq = std::clip(target_freq, dbsrx2_freq_range.min, dbsrx2_freq_range.max); +    //target_freq = uhd::clip(target_freq, dbsrx2_freq_range.min, dbsrx2_freq_range.max);      //variables used in the calculation below      int scaler = target_freq > 1125e6 ? 2 : 4; @@ -330,7 +330,7 @@ void dbsrx2::set_gain(double gain, const std::string &name){   **********************************************************************/  void dbsrx2::set_bandwidth(double bandwidth){      //clip the input -    bandwidth = std::clip<double>(bandwidth, 4e6, 40e6); +    bandwidth = uhd::clip<double>(bandwidth, 4e6, 40e6);      _max2112_write_regs.lp = int((bandwidth/1e6 - 4)/0.29 + 12);      _bandwidth = double(4 + (_max2112_write_regs.lp - 12) * 0.29)*1e6; diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index 3e3cf00f2..4d8222a52 100644 --- a/host/lib/usrp/dboard/db_rfx.cpp +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -37,7 +37,7 @@  #include <uhd/usrp/subdev_props.hpp>  #include <uhd/types/ranges.hpp>  #include <uhd/types/sensors.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/utils/assert_has.hpp>  #include <uhd/utils/static.hpp>  #include <uhd/utils/algorithm.hpp>  #include <uhd/utils/warning.hpp> @@ -245,7 +245,7 @@ static double rx_pga0_gain_to_dac_volts(double &gain, double range){      static const double slope = (max_volts-min_volts)/(range);      //calculate the voltage for the aux dac -    double dac_volts = std::clip<double>(gain*slope + min_volts, max_volts, min_volts); +    double dac_volts = uhd::clip<double>(gain*slope + min_volts, max_volts, min_volts);      //the actual gain setting      gain = (dac_volts - min_volts)/slope; diff --git a/host/lib/usrp/dboard/db_tvrx.cpp b/host/lib/usrp/dboard/db_tvrx.cpp index af025952e..d264c9ca4 100644 --- a/host/lib/usrp/dboard/db_tvrx.cpp +++ b/host/lib/usrp/dboard/db_tvrx.cpp @@ -28,7 +28,7 @@  //gain range: [0:1dB:115dB]  #include <uhd/utils/static.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/utils/assert_has.hpp>  #include <uhd/utils/algorithm.hpp>  #include <uhd/utils/warning.hpp>  #include <uhd/types/ranges.hpp> @@ -241,7 +241,7 @@ static std::string get_band(double freq) {  static double gain_interp(double gain, boost::array<double, 17> db_vector, boost::array<double, 17> volts_vector) {      double volts; -    gain = std::clip<double>(gain, db_vector.front(), db_vector.back()); //let's not get carried away here +    gain = uhd::clip<double>(gain, db_vector.front(), db_vector.back()); //let's not get carried away here      boost::uint8_t gain_step = 0;      //find which bin we're in @@ -288,7 +288,7 @@ static double rf_gain_to_voltage(double gain, double lo_freq){      //this is the voltage at the USRP DAC output      double dac_volts = gain_volts / opamp_gain; -    dac_volts = std::clip<double>(dac_volts, 0.0, 3.3); +    dac_volts = uhd::clip<double>(dac_volts, 0.0, 3.3);      if (tvrx_debug) std::cerr << boost::format(          "tvrx RF AGC gain: %f dB, dac_volts: %f V" @@ -311,7 +311,7 @@ static double if_gain_to_voltage(double gain){      double gain_volts = gain_interp(gain, tvrx_if_gains_db, tvrx_gains_volts);      double dac_volts = gain_volts / opamp_gain; -    dac_volts = std::clip<double>(dac_volts, 0.0, 3.3); +    dac_volts = uhd::clip<double>(dac_volts, 0.0, 3.3);      if (tvrx_debug) std::cerr << boost::format(          "tvrx IF AGC gain: %f dB, dac_volts: %f V" diff --git a/host/lib/usrp/dboard/db_unknown.cpp b/host/lib/usrp/dboard/db_unknown.cpp index f0a4c000e..cef4bee4a 100644 --- a/host/lib/usrp/dboard/db_unknown.cpp +++ b/host/lib/usrp/dboard/db_unknown.cpp @@ -17,7 +17,7 @@  #include <uhd/usrp/subdev_props.hpp>  #include <uhd/types/ranges.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/utils/assert_has.hpp>  #include <uhd/utils/static.hpp>  #include <uhd/utils/warning.hpp>  #include <uhd/usrp/dboard_base.hpp> diff --git a/host/lib/usrp/dboard/db_wbx.cpp b/host/lib/usrp/dboard/db_wbx.cpp index 0bc2d0ca1..2e9a1edc8 100644 --- a/host/lib/usrp/dboard/db_wbx.cpp +++ b/host/lib/usrp/dboard/db_wbx.cpp @@ -69,7 +69,7 @@  #include <uhd/usrp/subdev_props.hpp>  #include <uhd/types/ranges.hpp>  #include <uhd/types/sensors.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/utils/assert_has.hpp>  #include <uhd/utils/static.hpp>  #include <uhd/utils/algorithm.hpp>  #include <uhd/utils/warning.hpp> diff --git a/host/lib/usrp/dboard/db_xcvr2450.cpp b/host/lib/usrp/dboard/db_xcvr2450.cpp index f4f74eb86..9d25b30a5 100644 --- a/host/lib/usrp/dboard/db_xcvr2450.cpp +++ b/host/lib/usrp/dboard/db_xcvr2450.cpp @@ -49,7 +49,7 @@  #include "max2829_regs.hpp"  #include <uhd/utils/static.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/utils/assert_has.hpp>  #include <uhd/utils/algorithm.hpp>  #include <uhd/utils/warning.hpp>  #include <uhd/types/ranges.hpp> @@ -358,7 +358,7 @@ void xcvr2450::set_rx_ant(const std::string &ant){   */  static int gain_to_tx_vga_reg(double &gain){      //calculate the register value -    int reg = std::clip(boost::math::iround(gain*60/30.0) + 3, 0, 63); +    int reg = uhd::clip(boost::math::iround(gain*60/30.0) + 3, 0, 63);      //calculate the actual gain value      if (reg < 4)       gain = 0; @@ -376,7 +376,7 @@ static int gain_to_tx_vga_reg(double &gain){   * \return gain enum value   */  static max2829_regs_t::tx_baseband_gain_t gain_to_tx_bb_reg(double &gain){ -    int reg = std::clip(boost::math::iround(gain*3/5.0), 0, 3); +    int reg = uhd::clip(boost::math::iround(gain*3/5.0), 0, 3);      switch(reg){      case 0:          gain = 0; @@ -401,7 +401,7 @@ static max2829_regs_t::tx_baseband_gain_t gain_to_tx_bb_reg(double &gain){   * \return 5 bit the register value   */  static int gain_to_rx_vga_reg(double &gain){ -    int reg = std::clip(boost::math::iround(gain/2.0), 0, 31); +    int reg = uhd::clip(boost::math::iround(gain/2.0), 0, 31);      gain = double(reg*2);      return reg;  } @@ -413,7 +413,7 @@ static int gain_to_rx_vga_reg(double &gain){   * \return 2 bit the register value   */  static int gain_to_rx_lna_reg(double &gain){ -    int reg = std::clip(boost::math::iround(gain*2/30.5) + 1, 0, 3); +    int reg = uhd::clip(boost::math::iround(gain*2/30.5) + 1, 0, 3);      switch(reg){      case 0:      case 1: gain = 0;    break; @@ -456,7 +456,7 @@ void xcvr2450::set_rx_gain(double gain, const std::string &name){   * Bandwidth Handling   **********************************************************************/  static max2829_regs_t::tx_lpf_coarse_adj_t bandwidth_to_tx_lpf_coarse_reg(double &bandwidth){ -    int reg = std::clip(boost::math::iround((bandwidth-6.0e6)/6.0e6), 1, 3); +    int reg = uhd::clip(boost::math::iround((bandwidth-6.0e6)/6.0e6), 1, 3);      switch(reg){      case 1: // bandwidth < 15MHz @@ -473,7 +473,7 @@ static max2829_regs_t::tx_lpf_coarse_adj_t bandwidth_to_tx_lpf_coarse_reg(double  }  static max2829_regs_t::rx_lpf_fine_adj_t bandwidth_to_rx_lpf_fine_reg(double &bandwidth, double requested_bandwidth){ -    int reg = std::clip(boost::math::iround((requested_bandwidth/bandwidth)/0.05), 18, 22); +    int reg = uhd::clip(boost::math::iround((requested_bandwidth/bandwidth)/0.05), 18, 22);      switch(reg){      case 18: // requested_bandwidth < 92.5% @@ -496,7 +496,7 @@ static max2829_regs_t::rx_lpf_fine_adj_t bandwidth_to_rx_lpf_fine_reg(double &ba  }  static max2829_regs_t::rx_lpf_coarse_adj_t bandwidth_to_rx_lpf_coarse_reg(double &bandwidth){ -    int reg = std::clip(boost::math::iround((bandwidth-7.0e6)/1.0e6), 0, 11); +    int reg = uhd::clip(boost::math::iround((bandwidth-7.0e6)/1.0e6), 0, 11);      switch(reg){      case 0: // bandwidth < 7.5MHz diff --git a/host/lib/usrp/dboard_base.cpp b/host/lib/usrp/dboard_base.cpp index 6c4e29d9e..999dd9ffc 100644 --- a/host/lib/usrp/dboard_base.cpp +++ b/host/lib/usrp/dboard_base.cpp @@ -59,12 +59,12 @@ dboard_id_t dboard_base::get_tx_id(void){   **********************************************************************/  xcvr_dboard_base::xcvr_dboard_base(ctor_args_t args) : dboard_base(args){      if (get_rx_id() == dboard_id_t::none()){ -        throw std::runtime_error(str(boost::format( +        throw uhd::runtime_error(str(boost::format(              "cannot create xcvr board when the rx id is \"%s\""          ) % dboard_id_t::none().to_pp_string()));      }      if (get_tx_id() == dboard_id_t::none()){ -        throw std::runtime_error(str(boost::format( +        throw uhd::runtime_error(str(boost::format(              "cannot create xcvr board when the tx id is \"%s\""          ) % dboard_id_t::none().to_pp_string()));      } @@ -79,7 +79,7 @@ xcvr_dboard_base::~xcvr_dboard_base(void){   **********************************************************************/  rx_dboard_base::rx_dboard_base(ctor_args_t args) : dboard_base(args){      if (get_tx_id() != dboard_id_t::none()){ -        throw std::runtime_error(str(boost::format( +        throw uhd::runtime_error(str(boost::format(              "cannot create rx board when the tx id is \"%s\""              " -> expected a tx id of \"%s\""          ) % get_tx_id().to_pp_string() % dboard_id_t::none().to_pp_string())); @@ -91,11 +91,11 @@ rx_dboard_base::~rx_dboard_base(void){  }  void rx_dboard_base::tx_get(const wax::obj &, wax::obj &){ -    throw std::runtime_error("cannot call tx_get on a rx dboard"); +    throw uhd::runtime_error("cannot call tx_get on a rx dboard");  }  void rx_dboard_base::tx_set(const wax::obj &, const wax::obj &){ -    throw std::runtime_error("cannot call tx_set on a rx dboard"); +    throw uhd::runtime_error("cannot call tx_set on a rx dboard");  }  /*********************************************************************** @@ -103,7 +103,7 @@ void rx_dboard_base::tx_set(const wax::obj &, const wax::obj &){   **********************************************************************/  tx_dboard_base::tx_dboard_base(ctor_args_t args) : dboard_base(args){      if (get_rx_id() != dboard_id_t::none()){ -        throw std::runtime_error(str(boost::format( +        throw uhd::runtime_error(str(boost::format(              "cannot create tx board when the rx id is \"%s\""              " -> expected a rx id of \"%s\""          ) % get_rx_id().to_pp_string() % dboard_id_t::none().to_pp_string())); @@ -115,9 +115,9 @@ tx_dboard_base::~tx_dboard_base(void){  }  void tx_dboard_base::rx_get(const wax::obj &, wax::obj &){ -    throw std::runtime_error("cannot call rx_get on a tx dboard"); +    throw uhd::runtime_error("cannot call rx_get on a tx dboard");  }  void tx_dboard_base::rx_set(const wax::obj &, const wax::obj &){ -    throw std::runtime_error("cannot call rx_set on a tx dboard"); +    throw uhd::runtime_error("cannot call rx_set on a tx dboard");  } diff --git a/host/lib/usrp/dboard_eeprom.cpp b/host/lib/usrp/dboard_eeprom.cpp index c47390bf8..c1e44fb74 100644 --- a/host/lib/usrp/dboard_eeprom.cpp +++ b/host/lib/usrp/dboard_eeprom.cpp @@ -16,7 +16,8 @@  //  #include <uhd/usrp/dboard_eeprom.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp> +#include <boost/foreach.hpp>  #include <boost/format.hpp>  #include <algorithm>  #include <iostream> @@ -128,7 +129,7 @@ void dboard_eeprom_t::load(i2c_iface &iface, boost::uint8_t addr){              &bytes.at(DB_EEPROM_SERIAL+DB_EEPROM_SERIAL_LEN))          ); -    }catch(const uhd::assert_error &){ +    }catch(const uhd::assertion_error &){          id = dboard_id_t::none();          serial = "";      } diff --git a/host/lib/usrp/dboard_manager.cpp b/host/lib/usrp/dboard_manager.cpp index 75594e670..9055905b1 100644 --- a/host/lib/usrp/dboard_manager.cpp +++ b/host/lib/usrp/dboard_manager.cpp @@ -20,7 +20,7 @@  #include <uhd/usrp/subdev_props.hpp>  #include <uhd/utils/warning.hpp>  #include <uhd/utils/static.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp>  #include <uhd/types/dict.hpp>  #include <boost/tuple/tuple.hpp>  #include <boost/format.hpp> @@ -50,7 +50,7 @@ void dboard_manager::register_dboard(  ){      //std::cout << "registering: " << name << std::endl;      if (get_id_to_args_map().has_key(dboard_id)){ -        throw std::runtime_error(str(boost::format( +        throw uhd::key_error(str(boost::format(              "The dboard id %s is already registered to %s."          ) % dboard_id.to_string() % dboard_id.to_pp_string()));      } @@ -315,7 +315,7 @@ prop_names_t dboard_manager_impl::get_tx_subdev_names(void){  }  wax::obj dboard_manager_impl::get_rx_subdev(const std::string &subdev_name){ -    if (not _rx_dboards.has_key(subdev_name)) throw std::invalid_argument( +    if (not _rx_dboards.has_key(subdev_name)) throw uhd::key_error(          str(boost::format("Unknown rx subdev name %s") % subdev_name)      );      //get a link to the rx subdev proxy @@ -323,7 +323,7 @@ wax::obj dboard_manager_impl::get_rx_subdev(const std::string &subdev_name){  }  wax::obj dboard_manager_impl::get_tx_subdev(const std::string &subdev_name){ -    if (not _tx_dboards.has_key(subdev_name)) throw std::invalid_argument( +    if (not _tx_dboards.has_key(subdev_name)) throw uhd::key_error(          str(boost::format("Unknown tx subdev name %s") % subdev_name)      );      //get a link to the tx subdev proxy diff --git a/host/lib/usrp/dsp_utils.cpp b/host/lib/usrp/dsp_utils.cpp index 576c4639f..a3a557060 100644 --- a/host/lib/usrp/dsp_utils.cpp +++ b/host/lib/usrp/dsp_utils.cpp @@ -17,7 +17,7 @@  #include <uhd/usrp/dsp_utils.hpp>  #include <uhd/types/dict.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp>  #include <boost/assign/list_of.hpp>  #include <boost/tuple/tuple.hpp>  #include <boost/math/special_functions/round.hpp> @@ -44,7 +44,7 @@ boost::uint32_t dsp_type1::calc_rx_mux_word(subdev_conn_t subdev_conn){      case SUBDEV_CONN_COMPLEX_IQ: return (0x1 << 4) | (0x0 << 0); //DDC0Q=ADC0Q, DDC0I=ADC0I      case SUBDEV_CONN_COMPLEX_QI: return (0x0 << 4) | (0x1 << 0); //DDC0Q=ADC0I, DDC0I=ADC0Q      case SUBDEV_CONN_REAL_I:     return (0xf << 4) | (0x0 << 0); //DDC0Q=ZERO,  DDC0I=ADC0I -    case SUBDEV_CONN_REAL_Q:     return (0x1 << 4) | (0xf << 0); //DDC0Q=ADC0Q, DDC0I=ZERO +    case SUBDEV_CONN_REAL_Q:     return (0xf << 4) | (0x1 << 0); //DDC0Q=ZERO,  DDC0I=ADC0Q      default:                     UHD_THROW_INVALID_CODE_PATH();      }  } diff --git a/host/lib/usrp/gps_ctrl.cpp b/host/lib/usrp/gps_ctrl.cpp index b1062fa39..e0ab6de90 100644 --- a/host/lib/usrp/gps_ctrl.cpp +++ b/host/lib/usrp/gps_ctrl.cpp @@ -16,11 +16,10 @@  //  #include <uhd/usrp/gps_ctrl.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp>  #include <boost/cstdint.hpp> -#include <string>  #include <boost/date_time/posix_time/posix_time.hpp> -#include <boost/thread.hpp> +#include <boost/thread/thread.hpp>  #include <boost/algorithm/string/trim.hpp>  #include <boost/tokenizer.hpp> @@ -168,7 +167,7 @@ public:        break;      case GPS_TYPE_NONE:      default: -      throw std::runtime_error("get_time(): Unsupported GPS or no GPS detected\n"); +      throw uhd::runtime_error("get_time(): Unsupported GPS or no GPS detected\n");        break;      }      return now; diff --git a/host/lib/usrp/misc_utils.cpp b/host/lib/usrp/misc_utils.cpp index 2bad83b3c..ddcad41cf 100644 --- a/host/lib/usrp/misc_utils.cpp +++ b/host/lib/usrp/misc_utils.cpp @@ -16,7 +16,7 @@  //  #include <uhd/usrp/misc_utils.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/utils/assert_has.hpp>  #include <uhd/utils/algorithm.hpp>  #include <uhd/utils/gain_group.hpp>  #include <uhd/usrp/dboard_eeprom.hpp> @@ -167,7 +167,7 @@ static void verify_xx_subdev_spec(          BOOST_FOREACH(subdev_spec_pair_t &pair, subdev_spec){              //empty db name means select dboard automatically              if (pair.db_name.empty()){ -                if (dboard_names.size() != 1) throw std::runtime_error( +                if (dboard_names.size() != 1) throw uhd::value_error(                      "A daughterboard name must be provided for multi-slot motherboards: " + subdev_spec.to_string()                  );                  pair.db_name = dboard_names.front(); @@ -178,7 +178,7 @@ static void verify_xx_subdev_spec(              //empty sd name means select the subdev automatically              if (pair.sd_name.empty()){ -                if (subdev_names.size() != 1) throw std::runtime_error( +                if (subdev_names.size() != 1) throw uhd::value_error(                      "A subdevice name must be provided for multi-subdev daughterboards: " + subdev_spec.to_string()                  );                  pair.sd_name = subdev_names.front(); @@ -186,7 +186,7 @@ static void verify_xx_subdev_spec(              uhd::assert_has(subdev_names, pair.sd_name, xx_type + " subdev name");          }      }catch(const std::exception &e){ -        throw std::runtime_error(str(boost::format( +        throw uhd::value_error(str(boost::format(              "Validate %s subdev spec failed: %s\n    %s"          ) % xx_type % subdev_spec.to_string() % e.what()));      } @@ -196,11 +196,11 @@ static void verify_xx_subdev_spec(          wax::obj dboard = mboard[named_prop_t(dboard_prop, db_name)];          BOOST_FOREACH(const std::string &sd_name, dboard[DBOARD_PROP_SUBDEV_NAMES].as<prop_names_t>()){              try{ -                bool enable = std::has(subdev_spec, subdev_spec_pair_t(db_name, sd_name)); +                bool enable = uhd::has(subdev_spec, subdev_spec_pair_t(db_name, sd_name));                  dboard[named_prop_t(DBOARD_PROP_SUBDEV, sd_name)][SUBDEV_PROP_ENABLED] = enable;              }              catch(const std::exception &e){ -                throw std::runtime_error(str(boost::format( +                throw uhd::runtime_error(str(boost::format(                      "Cannot set enabled property on subdevice %s:%s\n    %s"                  ) % db_name % sd_name % e.what()));              } diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp index 73bac029d..83cbf339b 100644 --- a/host/lib/usrp/multi_usrp.cpp +++ b/host/lib/usrp/multi_usrp.cpp @@ -15,10 +15,10 @@  // along with this program.  If not, see <http://www.gnu.org/licenses/>.  // -#include "wrapper_utils.hpp"  #include <uhd/usrp/multi_usrp.hpp>  #include <uhd/usrp/tune_helper.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/usrp/mboard_iface.hpp> +#include <uhd/exception.hpp>  #include <uhd/utils/warning.hpp>  #include <uhd/utils/gain_group.hpp>  #include <uhd/usrp/subdev_props.hpp> @@ -29,8 +29,8 @@  #include <boost/thread.hpp>  #include <boost/foreach.hpp>  #include <boost/format.hpp> -#include <stdexcept>  #include <iostream> +#include <cmath>  using namespace uhd;  using namespace uhd::usrp; @@ -38,7 +38,48 @@ using namespace uhd::usrp;  const std::string multi_usrp::ALL_GAINS = "";  /*********************************************************************** - * Simple USRP Implementation + * Helper methods + **********************************************************************/ +static inline uhd::freq_range_t add_dsp_shift( +    const uhd::freq_range_t &range, +    wax::obj dsp +){ +    double codec_rate = dsp[uhd::usrp::DSP_PROP_CODEC_RATE].as<double>(); +    return uhd::freq_range_t(range.start() - codec_rate/2.0, range.stop() + codec_rate/2.0); +} + +static inline void do_samp_rate_warning_message( +    double target_rate, +    double actual_rate, +    const std::string &xx +){ +    static const double max_allowed_error = 1.0; //Sps +    if (std::abs(target_rate - actual_rate) > max_allowed_error){ +        uhd::warning::post(str(boost::format( +            "The hardware does not support the requested %s sample rate:\n" +            "Target sample rate: %f MSps\n" +            "Actual sample rate: %f MSps\n" +        ) % xx % (target_rate/1e6) % (actual_rate/1e6))); +    } +} + +static inline void do_tune_freq_warning_message( +    double target_freq, +    double actual_freq, +    const std::string &xx +){ +    static const double max_allowed_error = 1.0; //Hz +    if (std::abs(target_freq - actual_freq) > max_allowed_error){ +        uhd::warning::post(str(boost::format( +            "The hardware does not support the requested %s frequency:\n" +            "Target frequency: %f MHz\n" +            "Actual frequency: %f MHz\n" +        ) % xx % (target_freq/1e6) % (actual_freq/1e6))); +    } +} + +/*********************************************************************** + * Multi USRP Implementation   **********************************************************************/  class multi_usrp_impl : public multi_usrp{  public: @@ -85,17 +126,14 @@ public:          //----------- rx side of life ----------------------------------          for (size_t m = 0, chan = 0; m < get_num_mboards(); m++){ -            buff += str(boost::format( -                "  RX DSP %d: %s\n" -            ) % m -                % _rx_dsp(m)[DSP_PROP_NAME].as<std::string>() -            );              for (; chan < (m + 1)*get_rx_subdev_spec(m).size(); chan++){                  buff += str(boost::format(                      "  RX Channel: %u\n" +                    "    RX DSP: %s\n"                      "    RX Dboard: %s\n"                      "    RX Subdev: %s\n"                  ) % chan +                    % _rx_dsp(chan)[DSP_PROP_NAME].as<std::string>()                      % _rx_dboard(chan)[DBOARD_PROP_NAME].as<std::string>()                      % _rx_subdev(chan)[SUBDEV_PROP_NAME].as<std::string>()                  ); @@ -104,17 +142,14 @@ public:          //----------- tx side of life ----------------------------------          for (size_t m = 0, chan = 0; m < get_num_mboards(); m++){ -            buff += str(boost::format( -                "  TX DSP %d: %s\n" -            ) % m -                % _tx_dsp(m)[DSP_PROP_NAME].as<std::string>() -            );              for (; chan < (m + 1)*get_tx_subdev_spec(m).size(); chan++){                  buff += str(boost::format(                      "  TX Channel: %u\n" +                    "    TX DSP: %s\n"                      "    TX Dboard: %s\n"                      "    TX Subdev: %s\n"                  ) % chan +                    % _tx_dsp(chan)[DSP_PROP_NAME].as<std::string>()                      % _tx_dboard(chan)[DBOARD_PROP_NAME].as<std::string>()                      % _tx_subdev(chan)[SUBDEV_PROP_NAME].as<std::string>()                  ); @@ -159,7 +194,7 @@ public:          while(true){              if (get_time_last_pps() != time_start_last_pps) break;              if ((get_time_now() - time_start) > time_spec_t(1.1)){ -                throw std::runtime_error( +                throw uhd::runtime_error(                      "Board 0 may not be getting a PPS signal!\n"                      "No PPS detected within the time interval.\n"                      "See the application notes for your device.\n" @@ -194,9 +229,13 @@ public:          return true;      } -    void issue_stream_cmd(const stream_cmd_t &stream_cmd){ -        for (size_t m = 0; m < get_num_mboards(); m++){ -            _mboard(m)[MBOARD_PROP_STREAM_CMD] = stream_cmd; +    void issue_stream_cmd(const stream_cmd_t &stream_cmd, size_t chan){ +        if (chan != ALL_CHANS){ +            _rx_dsp(chan)[DSP_PROP_STREAM_CMD] = stream_cmd; +            return; +        } +        for (size_t c = 0; c < get_rx_num_channels(); c++){ +            issue_stream_cmd(stream_cmd, c);          }      } @@ -221,6 +260,10 @@ public:      std::vector<std::string> get_mboard_sensor_names(size_t mboard){          return _mboard(mboard)[MBOARD_PROP_SENSOR_NAMES].as<prop_names_t>();      } +     +    mboard_iface::sptr get_mboard_iface(size_t mboard){ +        return _mboard(mboard)[MBOARD_PROP_IFACE].as<mboard_iface::sptr>(); +    }      /*******************************************************************       * RX methods @@ -240,36 +283,44 @@ public:      }      size_t get_rx_num_channels(void){ -        return rx_cpm()*get_num_mboards(); //total num channels +        size_t sum = 0; +        for (size_t m = 0; m < get_num_mboards(); m++){ +            sum += get_rx_subdev_spec(m).size(); +        } +        return sum;      }      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){ -        for (size_t m = 0; m < get_num_mboards(); m++){ -            _rx_dsp(m)[DSP_PROP_HOST_RATE] = rate; +    void set_rx_rate(double rate, size_t chan){ +        if (chan != ALL_CHANS){ +            _rx_dsp(chan)[DSP_PROP_HOST_RATE] = rate; +            do_samp_rate_warning_message(rate, get_rx_rate(chan), "RX"); +            return; +        } +        for (size_t c = 0; c < get_rx_num_channels(); c++){ +            set_rx_rate(rate, c);          } -        do_samp_rate_warning_message(rate, get_rx_rate(), "RX");      } -    double get_rx_rate(void){ -        return _rx_dsp(0)[DSP_PROP_HOST_RATE].as<double>(); +    double get_rx_rate(size_t chan){ +        return _rx_dsp(chan)[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/rx_cpm()), chan%rx_cpm(), tune_request); +        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/rx_cpm()), chan%rx_cpm()); +        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(chan/rx_cpm())); +        return add_dsp_shift(_rx_subdev(chan)[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _rx_dsp(chan));      }      void set_rx_gain(double gain, const std::string &name, size_t chan){ @@ -342,32 +393,40 @@ public:      }      size_t get_tx_num_channels(void){ -        return tx_cpm()*get_num_mboards(); //total num channels +        size_t sum = 0; +        for (size_t m = 0; m < get_num_mboards(); m++){ +            sum += get_tx_subdev_spec(m).size(); +        } +        return sum;      } -    void set_tx_rate(double rate){ -        for (size_t m = 0; m < get_num_mboards(); m++){ -            _tx_dsp(m)[DSP_PROP_HOST_RATE] = rate; +    void set_tx_rate(double rate, size_t chan){ +        if (chan != ALL_CHANS){ +            _tx_dsp(chan)[DSP_PROP_HOST_RATE] = rate; +            do_samp_rate_warning_message(rate, get_tx_rate(chan), "TX"); +            return; +        } +        for (size_t c = 0; c < get_tx_num_channels(); c++){ +            set_tx_rate(rate, c);          } -        do_samp_rate_warning_message(rate, get_tx_rate(), "TX");      } -    double get_tx_rate(void){ -        return _tx_dsp(0)[DSP_PROP_HOST_RATE].as<double>(); +    double get_tx_rate(size_t chan){ +        return _tx_dsp(chan)[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/tx_cpm()), chan%tx_cpm(), tune_request); +        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/tx_cpm()), chan%tx_cpm()); +        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(chan/tx_cpm())); +        return add_dsp_shift(_tx_subdev(chan)[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _tx_dsp(chan));      }      void set_tx_gain(double gain, const std::string &name, size_t chan){ @@ -421,58 +480,75 @@ public:  private:      device::sptr _dev; -    size_t rx_cpm(void){ //channels per mboard -        size_t nchan = get_rx_subdev_spec(0).size(); -        for (size_t m = 1; m < get_num_mboards(); m++){ -            if (nchan != get_rx_subdev_spec(m).size()){ -                throw std::runtime_error("rx subdev spec size inconsistent across all mboards"); -            } +    struct mboard_chan_pair{ +        size_t mboard, chan; +        mboard_chan_pair(void): mboard(0), chan(0){} +    }; + +    mboard_chan_pair rx_chan_to_mcp(size_t chan){ +        mboard_chan_pair mcp; +        mcp.chan = chan; +        for (mcp.mboard = 0; mcp.mboard < get_num_mboards(); mcp.mboard++){ +            size_t sss = get_rx_subdev_spec(mcp.mboard).size(); +            if (mcp.chan < sss) break; +            mcp.chan -= sss;          } -        return nchan; +        return mcp;      } -    size_t tx_cpm(void){ //channels per mboard -        size_t nchan = get_tx_subdev_spec(0).size(); -        for (size_t m = 1; m < get_num_mboards(); m++){ -            if (nchan != get_tx_subdev_spec(m).size()){ -                throw std::runtime_error("tx subdev spec size inconsistent across all mboards"); -            } +    mboard_chan_pair tx_chan_to_mcp(size_t chan){ +        mboard_chan_pair mcp; +        mcp.chan = chan; +        for (mcp.mboard = 0; mcp.mboard < get_num_mboards(); mcp.mboard++){ +            size_t sss = get_tx_subdev_spec(mcp.mboard).size(); +            if (mcp.chan < sss) break; +            mcp.chan -= sss;          } -        return nchan; +        return mcp;      }      wax::obj _mboard(size_t mboard){          std::string mb_name = (*_dev)[DEVICE_PROP_MBOARD_NAMES].as<prop_names_t>().at(mboard);          return (*_dev)[named_prop_t(DEVICE_PROP_MBOARD, mb_name)];      } -    wax::obj _rx_dsp(size_t mboard){ -        return _mboard(mboard)[MBOARD_PROP_RX_DSP]; +    wax::obj _rx_dsp(size_t chan){ +        mboard_chan_pair mcp = rx_chan_to_mcp(chan); +        prop_names_t dsp_names = _mboard(mcp.mboard)[MBOARD_PROP_RX_DSP_NAMES].as<prop_names_t>(); +        return _mboard(mcp.mboard)[named_prop_t(MBOARD_PROP_RX_DSP, dsp_names.at(mcp.chan))];      } -    wax::obj _tx_dsp(size_t mboard){ -        return _mboard(mboard)[MBOARD_PROP_TX_DSP]; +    wax::obj _tx_dsp(size_t chan){ +        mboard_chan_pair mcp = tx_chan_to_mcp(chan); +        prop_names_t dsp_names = _mboard(mcp.mboard)[MBOARD_PROP_TX_DSP_NAMES].as<prop_names_t>(); +        return _mboard(mcp.mboard)[named_prop_t(MBOARD_PROP_TX_DSP, dsp_names.at(mcp.chan))];      }      wax::obj _rx_dboard(size_t chan){ -        std::string db_name = get_rx_subdev_spec(chan/rx_cpm()).at(chan%rx_cpm()).db_name; -        return _mboard(chan/rx_cpm())[named_prop_t(MBOARD_PROP_RX_DBOARD, db_name)]; +        mboard_chan_pair mcp = rx_chan_to_mcp(chan); +        std::string db_name = get_rx_subdev_spec(mcp.mboard).at(mcp.chan).db_name; +        return _mboard(mcp.mboard)[named_prop_t(MBOARD_PROP_RX_DBOARD, db_name)];      }      wax::obj _tx_dboard(size_t chan){ -        std::string db_name = get_tx_subdev_spec(chan/tx_cpm()).at(chan%tx_cpm()).db_name; -        return _mboard(chan/tx_cpm())[named_prop_t(MBOARD_PROP_TX_DBOARD, db_name)]; +        mboard_chan_pair mcp = tx_chan_to_mcp(chan); +        std::string db_name = get_tx_subdev_spec(mcp.mboard).at(mcp.chan).db_name; +        return _mboard(mcp.mboard)[named_prop_t(MBOARD_PROP_TX_DBOARD, db_name)];      }      wax::obj _rx_subdev(size_t chan){ -        std::string sd_name = get_rx_subdev_spec(chan/rx_cpm()).at(chan%rx_cpm()).sd_name; +        mboard_chan_pair mcp = rx_chan_to_mcp(chan); +        std::string sd_name = get_rx_subdev_spec(mcp.mboard).at(mcp.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 = get_tx_subdev_spec(chan/tx_cpm()).at(chan%tx_cpm()).sd_name; +        mboard_chan_pair mcp = tx_chan_to_mcp(chan); +        std::string sd_name = get_tx_subdev_spec(mcp.mboard).at(mcp.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 = get_rx_subdev_spec(chan/rx_cpm()).at(chan%rx_cpm()).sd_name; +        mboard_chan_pair mcp = rx_chan_to_mcp(chan); +        std::string sd_name = get_rx_subdev_spec(mcp.mboard).at(mcp.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 = get_tx_subdev_spec(chan/tx_cpm()).at(chan%tx_cpm()).sd_name; +        mboard_chan_pair mcp = tx_chan_to_mcp(chan); +        std::string sd_name = get_tx_subdev_spec(mcp.mboard).at(mcp.chan).sd_name;          return _tx_dboard(chan)[named_prop_t(DBOARD_PROP_GAIN_GROUP, sd_name)].as<gain_group::sptr>();      }  }; diff --git a/host/lib/usrp/subdev_spec.cpp b/host/lib/usrp/subdev_spec.cpp index d5d950f1f..6912afec8 100644 --- a/host/lib/usrp/subdev_spec.cpp +++ b/host/lib/usrp/subdev_spec.cpp @@ -16,11 +16,11 @@  //  #include <uhd/usrp/subdev_spec.hpp> +#include <uhd/exception.hpp>  #include <boost/algorithm/string.hpp> //for split  #include <boost/tokenizer.hpp>  #include <boost/format.hpp>  #include <boost/foreach.hpp> -#include <stdexcept>  #include <sstream>  #include <vector> @@ -51,7 +51,7 @@ subdev_spec_t::subdev_spec_t(const std::string &markup){          switch(db_sd.size()){          case 1: this->push_back(subdev_spec_pair_t("", db_sd.front())); break;          case 2: this->push_back(subdev_spec_pair_t(db_sd.front(), db_sd.back())); break; -        default: throw std::runtime_error("invalid subdev-spec markup string: "+markup); +        default: throw uhd::value_error("invalid subdev-spec markup string: "+markup);          }      }  } diff --git a/host/lib/usrp/tune_helper.cpp b/host/lib/usrp/tune_helper.cpp index eccee7f4b..ced80c187 100644 --- a/host/lib/usrp/tune_helper.cpp +++ b/host/lib/usrp/tune_helper.cpp @@ -30,12 +30,11 @@ using namespace uhd::usrp;   **********************************************************************/  static tune_result_t tune_xx_subdev_and_dsp(      dboard_iface::unit_t unit, -    wax::obj subdev, wax::obj dsp, size_t chan, +    wax::obj subdev, wax::obj dsp,      const tune_request_t &tune_request  ){      wax::obj subdev_freq_proxy = subdev[SUBDEV_PROP_FREQ]; -    std::string freq_name = dsp[DSP_PROP_FREQ_SHIFT_NAMES].as<prop_names_t>().at(chan); -    wax::obj dsp_freq_proxy = dsp[named_prop_t(DSP_PROP_FREQ_SHIFT, freq_name)]; +    wax::obj dsp_freq_proxy = dsp[DSP_PROP_FREQ_SHIFT];      //------------------------------------------------------------------      //-- calculate the LO offset, only used with automatic policy @@ -105,13 +104,11 @@ static tune_result_t tune_xx_subdev_and_dsp(  }  static double derive_freq_from_xx_subdev_and_dsp( -    dboard_iface::unit_t unit, -    wax::obj subdev, wax::obj dsp, size_t chan +    dboard_iface::unit_t unit, wax::obj subdev, wax::obj dsp  ){      //extract actual dsp and IF frequencies      double actual_inter_freq = subdev[SUBDEV_PROP_FREQ].as<double>(); -    std::string freq_name = dsp[DSP_PROP_FREQ_SHIFT_NAMES].as<prop_names_t>().at(chan); -    double actual_dsp_freq = dsp[named_prop_t(DSP_PROP_FREQ_SHIFT, freq_name)].as<double>(); +    double actual_dsp_freq = dsp[DSP_PROP_FREQ_SHIFT].as<double>();      //invert the sign on the dsp freq given the following conditions      if (unit == dboard_iface::UNIT_TX) actual_dsp_freq *= -1.0; @@ -123,30 +120,28 @@ static double derive_freq_from_xx_subdev_and_dsp(   * RX Tune   **********************************************************************/  tune_result_t usrp::tune_rx_subdev_and_dsp( -    wax::obj subdev, wax::obj ddc, size_t chan, -    const tune_request_t &tune_request +    wax::obj subdev, wax::obj ddc, const tune_request_t &tune_request  ){ -    return tune_xx_subdev_and_dsp(dboard_iface::UNIT_RX, subdev, ddc, chan, tune_request); +    return tune_xx_subdev_and_dsp(dboard_iface::UNIT_RX, subdev, ddc, tune_request);  }  double usrp::derive_freq_from_rx_subdev_and_dsp( -    wax::obj subdev, wax::obj ddc, size_t chan +    wax::obj subdev, wax::obj ddc  ){ -    return derive_freq_from_xx_subdev_and_dsp(dboard_iface::UNIT_RX, subdev, ddc, chan); +    return derive_freq_from_xx_subdev_and_dsp(dboard_iface::UNIT_RX, subdev, ddc);  }  /***********************************************************************   * TX Tune   **********************************************************************/  tune_result_t usrp::tune_tx_subdev_and_dsp( -    wax::obj subdev, wax::obj duc, size_t chan, -    const tune_request_t &tune_request +    wax::obj subdev, wax::obj duc, const tune_request_t &tune_request  ){ -    return tune_xx_subdev_and_dsp(dboard_iface::UNIT_TX, subdev, duc, chan, tune_request); +    return tune_xx_subdev_and_dsp(dboard_iface::UNIT_TX, subdev, duc, tune_request);  }  double usrp::derive_freq_from_tx_subdev_and_dsp( -    wax::obj subdev, wax::obj duc, size_t chan +    wax::obj subdev, wax::obj duc  ){ -    return derive_freq_from_xx_subdev_and_dsp(dboard_iface::UNIT_TX, subdev, duc, chan); +    return derive_freq_from_xx_subdev_and_dsp(dboard_iface::UNIT_TX, subdev, duc);  } diff --git a/host/lib/usrp/usrp1/clock_ctrl.cpp b/host/lib/usrp/usrp1/clock_ctrl.cpp index 156f2b0c4..df5353b54 100644 --- a/host/lib/usrp/usrp1/clock_ctrl.cpp +++ b/host/lib/usrp/usrp1/clock_ctrl.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 @@ -16,13 +16,6 @@  //  #include "clock_ctrl.hpp" -#include "fpga_regs_standard.h" -#include <uhd/utils/assert.hpp> -#include <boost/cstdint.hpp> -#include <boost/assign/list_of.hpp> -#include <boost/foreach.hpp> -#include <utility> -#include <iostream>  using namespace uhd; diff --git a/host/lib/usrp/usrp1/codec_ctrl.cpp b/host/lib/usrp/usrp1/codec_ctrl.cpp index f3816b377..1b4411002 100644 --- a/host/lib/usrp/usrp1/codec_ctrl.cpp +++ b/host/lib/usrp/usrp1/codec_ctrl.cpp @@ -20,7 +20,7 @@  #include "clock_ctrl.hpp"  #include "ad9862_regs.hpp"  #include <uhd/types/dict.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp>  #include <uhd/utils/algorithm.hpp>  #include <uhd/utils/byteswap.hpp>  #include <boost/cstdint.hpp> @@ -162,7 +162,7 @@ static const int mtpgw = 255; //maximum tx pga gain word  void usrp1_codec_ctrl_impl::set_tx_pga_gain(double gain){      int gain_word = int(mtpgw*(gain - tx_pga_gain_range.start())/(tx_pga_gain_range.stop() - tx_pga_gain_range.start())); -    _ad9862_regs.tx_pga_gain = std::clip(gain_word, 0, mtpgw); +    _ad9862_regs.tx_pga_gain = uhd::clip(gain_word, 0, mtpgw);      this->send_reg(16);  } @@ -174,7 +174,7 @@ static const int mrpgw = 0x14; //maximum rx pga gain word  void usrp1_codec_ctrl_impl::set_rx_pga_gain(double gain, char which){      int gain_word = int(mrpgw*(gain - rx_pga_gain_range.start())/(rx_pga_gain_range.stop() - rx_pga_gain_range.start())); -    gain_word = std::clip(gain_word, 0, mrpgw); +    gain_word = uhd::clip(gain_word, 0, mrpgw);      switch(which){      case 'A':          _ad9862_regs.rx_pga_a = gain_word; @@ -264,7 +264,7 @@ void usrp1_codec_ctrl_impl::write_aux_dac(aux_dac_t which, double volts)  {      //special case for aux dac d (aka sigma delta word)      if (which == AUX_DAC_D) { -        boost::uint16_t dac_word = std::clip(boost::math::iround(volts*0xfff/3.3), 0, 0xfff); +        boost::uint16_t dac_word = uhd::clip(boost::math::iround(volts*0xfff/3.3), 0, 0xfff);          _ad9862_regs.sig_delt_11_4 = boost::uint8_t(dac_word >> 4);          _ad9862_regs.sig_delt_3_0 = boost::uint8_t(dac_word & 0xf);          this->send_reg(42); @@ -273,7 +273,7 @@ void usrp1_codec_ctrl_impl::write_aux_dac(aux_dac_t which, double volts)      }      //calculate the dac word for aux dac a, b, c -    boost::uint8_t dac_word = std::clip(boost::math::iround(volts*0xff/3.3), 0, 0xff); +    boost::uint8_t dac_word = uhd::clip(boost::math::iround(volts*0xff/3.3), 0, 0xff);      //setup a lookup table for the aux dac params (reg ref, reg addr)      typedef boost::tuple<boost::uint8_t*, boost::uint8_t> dac_params_t; @@ -303,8 +303,8 @@ void usrp1_codec_ctrl_impl::send_reg(boost::uint8_t addr)          std::cout << "codec control write reg: 0x";          std::cout << std::setw(8) << std::hex << reg << std::endl;      } -    _iface->transact_spi(_spi_slave, -                         spi_config_t::EDGE_RISE, reg, 16, false); +    _iface->write_spi(_spi_slave, +                         spi_config_t::EDGE_RISE, reg, 16);  }  void usrp1_codec_ctrl_impl::recv_reg(boost::uint8_t addr) @@ -317,8 +317,8 @@ void usrp1_codec_ctrl_impl::recv_reg(boost::uint8_t addr)          std::cout << std::setw(8) << std::hex << reg << std::endl;      } -    boost::uint32_t ret = _iface->transact_spi(_spi_slave, -                                        spi_config_t::EDGE_RISE, reg, 16, true); +    boost::uint32_t ret = _iface->read_spi(_spi_slave, +                                        spi_config_t::EDGE_RISE, reg, 16);      if (codec_debug) {          std::cout.fill('0'); diff --git a/host/lib/usrp/usrp1/codec_impl.cpp b/host/lib/usrp/usrp1/codec_impl.cpp index 14ecd2d2e..7e4032131 100644 --- a/host/lib/usrp/usrp1/codec_impl.cpp +++ b/host/lib/usrp/usrp1/codec_impl.cpp @@ -16,7 +16,7 @@  //  #include "usrp1_impl.hpp" -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp>  #include <uhd/usrp/codec_props.hpp>  #include <boost/bind.hpp>  #include <boost/foreach.hpp> diff --git a/host/lib/usrp/usrp1/dboard_iface.cpp b/host/lib/usrp/usrp1/dboard_iface.cpp index eec4a52db..3f3a98b7a 100644 --- a/host/lib/usrp/usrp1/dboard_iface.cpp +++ b/host/lib/usrp/usrp1/dboard_iface.cpp @@ -24,7 +24,7 @@  #include "codec_ctrl.hpp"  #include <uhd/usrp/dboard_iface.hpp>  #include <uhd/types/dict.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/utils/assert_has.hpp>  #include <boost/assign/list_of.hpp>  #include <iostream> @@ -329,7 +329,7 @@ static boost::uint32_t unit_to_otw_spi_dev(dboard_iface::unit_t unit,          else              break;      } -    throw std::invalid_argument("unknown unit type"); +    UHD_THROW_INVALID_CODE_PATH();  }  void usrp1_dboard_iface::write_spi(unit_t unit, @@ -337,8 +337,8 @@ void usrp1_dboard_iface::write_spi(unit_t unit,                                     boost::uint32_t data,                                     size_t num_bits)  { -    _iface->transact_spi(unit_to_otw_spi_dev(unit, _dboard_slot), -                         config, data, num_bits, false); +    _iface->write_spi(unit_to_otw_spi_dev(unit, _dboard_slot), +                         config, data, num_bits);  }  boost::uint32_t usrp1_dboard_iface::read_write_spi(unit_t unit, @@ -346,8 +346,8 @@ boost::uint32_t usrp1_dboard_iface::read_write_spi(unit_t unit,                                                     boost::uint32_t data,                                                     size_t num_bits)  { -    return _iface->transact_spi(unit_to_otw_spi_dev(unit, _dboard_slot), -                                config, data, num_bits, true); +    return _iface->read_spi(unit_to_otw_spi_dev(unit, _dboard_slot), +                                config, data, num_bits);  }  /*********************************************************************** diff --git a/host/lib/usrp/usrp1/dboard_impl.cpp b/host/lib/usrp/usrp1/dboard_impl.cpp index 2130960fb..02906fc45 100644 --- a/host/lib/usrp/usrp1/dboard_impl.cpp +++ b/host/lib/usrp/usrp1/dboard_impl.cpp @@ -19,7 +19,7 @@  #include "usrp_i2c_addr.h"  #include <uhd/usrp/dsp_utils.hpp>  #include <uhd/usrp/misc_utils.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp>  #include <uhd/usrp/dboard_props.hpp>  #include <uhd/usrp/subdev_props.hpp>  #include <boost/bind.hpp> diff --git a/host/lib/usrp/usrp1/dsp_impl.cpp b/host/lib/usrp/usrp1/dsp_impl.cpp index 370f4831f..8152c4e34 100644 --- a/host/lib/usrp/usrp1/dsp_impl.cpp +++ b/host/lib/usrp/usrp1/dsp_impl.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 @@ -34,23 +34,25 @@ using namespace uhd::usrp;   **********************************************************************/  void usrp1_impl::rx_dsp_init(void)  { -    _rx_dsp_proxy = wax_obj_proxy::make( -        boost::bind(&usrp1_impl::rx_dsp_get, this, _1, _2), -        boost::bind(&usrp1_impl::rx_dsp_set, this, _1, _2)); - -    rx_dsp_set(DSP_PROP_HOST_RATE, _clock_ctrl->get_master_clock_freq() / 16); +    for (size_t i = 0; i < this->get_num_ddcs(); i++){ +        _rx_dsp_proxies[str(boost::format("DSP%d")%i)] = wax_obj_proxy::make( +            boost::bind(&usrp1_impl::rx_dsp_get, this, _1, _2, i), +            boost::bind(&usrp1_impl::rx_dsp_set, this, _1, _2, i) +        ); +        rx_dsp_set(DSP_PROP_HOST_RATE, _clock_ctrl->get_master_clock_freq() / 16, i); +    }  }  /***********************************************************************   * RX DDC Get   **********************************************************************/ -void usrp1_impl::rx_dsp_get(const wax::obj &key_, wax::obj &val){ +void usrp1_impl::rx_dsp_get(const wax::obj &key_, wax::obj &val, size_t which_dsp){      named_prop_t key = named_prop_t::extract(key_);      switch(key.as<dsp_prop_t>()){      case DSP_PROP_NAME: -        val = str(boost::format("usrp1 ddc %uX %s") -            % this->get_num_ddcs() +        val = str(boost::format("usrp1 ddc%d %s") +            % which_dsp              % (this->has_rx_halfband()? "+ hb" : "")          );          return; @@ -60,16 +62,7 @@ void usrp1_impl::rx_dsp_get(const wax::obj &key_, wax::obj &val){          return;      case DSP_PROP_FREQ_SHIFT: -        val = _rx_dsp_freqs[key.name]; -        return; - -    case DSP_PROP_FREQ_SHIFT_NAMES:{ -            prop_names_t names; -            for(size_t i = 0; i < this->get_num_ddcs(); i++){ -                names.push_back(boost::lexical_cast<std::string>(i)); -            } -            val = names; -        } +        val = _rx_dsp_freqs[which_dsp];          return;      case DSP_PROP_CODEC_RATE: @@ -88,7 +81,7 @@ void usrp1_impl::rx_dsp_get(const wax::obj &key_, wax::obj &val){  /***********************************************************************   * RX DDC Set   **********************************************************************/ -void usrp1_impl::rx_dsp_set(const wax::obj &key_, const wax::obj &val){ +void usrp1_impl::rx_dsp_set(const wax::obj &key_, const wax::obj &val, size_t which_dsp){      named_prop_t key = named_prop_t::extract(key_);      switch(key.as<dsp_prop_t>()) { @@ -97,16 +90,17 @@ void usrp1_impl::rx_dsp_set(const wax::obj &key_, const wax::obj &val){              boost::uint32_t reg_word = dsp_type1::calc_cordic_word_and_update(                  new_freq, _clock_ctrl->get_master_clock_freq()); -            static const uhd::dict<std::string, boost::uint32_t> -            freq_name_to_reg_val = boost::assign::map_list_of -                ("0", FR_RX_FREQ_0) ("1", FR_RX_FREQ_1) -                ("2", FR_RX_FREQ_2) ("3", FR_RX_FREQ_3) -            ; -            _iface->poke32(freq_name_to_reg_val[key.name], ~reg_word + 1); -            _rx_dsp_freqs[key.name] = new_freq; +            static const boost::uint32_t dsp_index_to_reg_val[4] = { +                FR_RX_FREQ_0, FR_RX_FREQ_1, FR_RX_FREQ_2, FR_RX_FREQ_3 +            }; +            _iface->poke32(dsp_index_to_reg_val[which_dsp], ~reg_word + 1); +            _rx_dsp_freqs[which_dsp] = new_freq;              return;          } -    case DSP_PROP_HOST_RATE: { + +    case DSP_PROP_HOST_RATE: +        if (which_dsp != 0) return; //only for dsp[0] as this is vectorized +        {              size_t rate = size_t(_clock_ctrl->get_master_clock_freq() / val.as<double>());              if ((rate & 0x01) || (rate < 4) || (rate > 256)) { @@ -123,6 +117,11 @@ void usrp1_impl::rx_dsp_set(const wax::obj &key_, const wax::obj &val){          }          return; +    case DSP_PROP_STREAM_CMD: +        if (which_dsp != 0) return; //only for dsp[0] as this is vectorized +        _soft_time_ctrl->issue_stream_cmd(val.as<stream_cmd_t>()); +        return; +      default: UHD_THROW_PROP_SET_ERROR();      } @@ -133,24 +132,25 @@ void usrp1_impl::rx_dsp_set(const wax::obj &key_, const wax::obj &val){   **********************************************************************/  void usrp1_impl::tx_dsp_init(void)  { -    _tx_dsp_proxy = wax_obj_proxy::make( -                          boost::bind(&usrp1_impl::tx_dsp_get, this, _1, _2), -                          boost::bind(&usrp1_impl::tx_dsp_set, this, _1, _2)); - -    //initial config and update -    tx_dsp_set(DSP_PROP_HOST_RATE, _clock_ctrl->get_master_clock_freq() * 2 / 16); +    for (size_t i = 0; i < this->get_num_ducs(); i++){ +        _tx_dsp_proxies[str(boost::format("DSP%d")%i)] = wax_obj_proxy::make( +            boost::bind(&usrp1_impl::tx_dsp_get, this, _1, _2, i), +            boost::bind(&usrp1_impl::tx_dsp_set, this, _1, _2, i) +        ); +        tx_dsp_set(DSP_PROP_HOST_RATE, _clock_ctrl->get_master_clock_freq() / 16, i); +    }  }  /***********************************************************************   * TX DUC Get   **********************************************************************/ -void usrp1_impl::tx_dsp_get(const wax::obj &key_, wax::obj &val){ +void usrp1_impl::tx_dsp_get(const wax::obj &key_, wax::obj &val, size_t which_dsp){      named_prop_t key = named_prop_t::extract(key_);      switch(key.as<dsp_prop_t>()) {      case DSP_PROP_NAME: -        val = str(boost::format("usrp1 duc %uX %s") -            % this->get_num_ducs() +        val = str(boost::format("usrp1 duc%d %s") +            % which_dsp              % (this->has_tx_halfband()? "+ hb" : "")          );          return; @@ -160,16 +160,7 @@ void usrp1_impl::tx_dsp_get(const wax::obj &key_, wax::obj &val){          return;      case DSP_PROP_FREQ_SHIFT: -        val = _tx_dsp_freqs[key.name]; -        return; - -    case DSP_PROP_FREQ_SHIFT_NAMES:{ -            prop_names_t names; -            for(size_t i = 0; i < this->get_num_ducs(); i++){ -                names.push_back(boost::lexical_cast<std::string>(i)); -            } -            val = names; -        } +        val = _tx_dsp_freqs[which_dsp];          return;      case DSP_PROP_CODEC_RATE: @@ -188,7 +179,7 @@ void usrp1_impl::tx_dsp_get(const wax::obj &key_, wax::obj &val){  /***********************************************************************   * TX DUC Set   **********************************************************************/ -void usrp1_impl::tx_dsp_set(const wax::obj &key_, const wax::obj &val){ +void usrp1_impl::tx_dsp_set(const wax::obj &key_, const wax::obj &val, size_t which_dsp){      named_prop_t key = named_prop_t::extract(key_);      switch(key.as<dsp_prop_t>()) { @@ -197,15 +188,17 @@ void usrp1_impl::tx_dsp_set(const wax::obj &key_, const wax::obj &val){              double new_freq = val.as<double>();              //map the freq shift key to a subdev spec to a particular codec chip -            std::string db_name = _tx_subdev_spec.at(boost::lexical_cast<size_t>(key.name)).db_name; +            std::string db_name = _tx_subdev_spec.at(which_dsp).db_name;              if (db_name == "A") _codec_ctrls[DBOARD_SLOT_A]->set_duc_freq(new_freq);              if (db_name == "B") _codec_ctrls[DBOARD_SLOT_B]->set_duc_freq(new_freq); -            _tx_dsp_freqs[key.name] = new_freq; +            _tx_dsp_freqs[which_dsp] = new_freq;              return;          } -    case DSP_PROP_HOST_RATE: { +    case DSP_PROP_HOST_RATE: +        if (which_dsp != 0) return; //only for dsp[0] as this is vectorized +        {              size_t rate = size_t(_clock_ctrl->get_master_clock_freq() * 2 / val.as<double>());              if ((rate & 0x01) || (rate < 8) || (rate > 512)) { diff --git a/host/lib/usrp/usrp1/io_impl.cpp b/host/lib/usrp/usrp1/io_impl.cpp index 8beeccf8f..b3268298e 100644 --- a/host/lib/usrp/usrp1/io_impl.cpp +++ b/host/lib/usrp/usrp1/io_impl.cpp @@ -18,6 +18,7 @@  #include "../../transport/vrt_packet_handler.hpp"  #include "usrp_commands.h"  #include "usrp1_impl.hpp" +#include <uhd/utils/safe_call.hpp>  #include <uhd/utils/thread_priority.hpp>  #include <uhd/transport/bounded_buffer.hpp>  #include <boost/bind.hpp> @@ -114,7 +115,7 @@ struct usrp1_impl::io_impl{      }      ~io_impl(void){ -        flush_send_buff(); +        UHD_SAFE_CALL(flush_send_buff();)      }      zero_copy_if::sptr data_transport; diff --git a/host/lib/usrp/usrp1/mboard_impl.cpp b/host/lib/usrp/usrp1/mboard_impl.cpp index 6d5bf466d..4e2fad6e5 100644 --- a/host/lib/usrp/usrp1/mboard_impl.cpp +++ b/host/lib/usrp/usrp1/mboard_impl.cpp @@ -25,7 +25,7 @@  #include <uhd/usrp/dboard_props.hpp>  #include <uhd/usrp/subdev_props.hpp>  #include <uhd/utils/warning.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/utils/assert_has.hpp>  #include <uhd/utils/images.hpp>  #include <boost/assign/list_of.hpp>  #include <boost/foreach.hpp> @@ -161,7 +161,7 @@ static boost::uint32_t calc_tx_mux(          //sanity check, only 1 channel per slot          slot_to_chan_count[pair.db_name]++;          if (slot_to_chan_count[pair.db_name] > 1){ -            throw std::runtime_error(str(boost::format( +            throw uhd::value_error(str(boost::format(                  "dboard slot %s assigned to multiple channels in subdev spec %s"              ) % pair.db_name % subdev_spec.to_string()));          } @@ -280,21 +280,19 @@ void usrp1_impl::mboard_get(const wax::obj &key_, wax::obj &val)          return;      case MBOARD_PROP_RX_DSP: -        UHD_ASSERT_THROW(key.name == ""); -        val = _rx_dsp_proxy->get_link(); +        val = _rx_dsp_proxies.get(key.name)->get_link();          return;      case MBOARD_PROP_RX_DSP_NAMES: -        val = prop_names_t(1, ""); +        val = _rx_dsp_proxies.keys();          return;      case MBOARD_PROP_TX_DSP: -        UHD_ASSERT_THROW(key.name == ""); -        val = _tx_dsp_proxy->get_link(); +        val = _tx_dsp_proxies.get(key.name)->get_link();          return;      case MBOARD_PROP_TX_DSP_NAMES: -        val = prop_names_t(1, ""); +        val = _tx_dsp_proxies.keys();          return;      case MBOARD_PROP_CLOCK_CONFIG: @@ -342,14 +340,10 @@ void usrp1_impl::mboard_set(const wax::obj &key, const wax::obj &val)      //handle the get request conditioned on the key      switch(key.as<mboard_prop_t>()){ -    case MBOARD_PROP_STREAM_CMD: -        _soft_time_ctrl->issue_stream_cmd(val.as<stream_cmd_t>()); -        return; -      case MBOARD_PROP_RX_SUBDEV_SPEC:          _rx_subdev_spec = val.as<subdev_spec_t>();          if (_rx_subdev_spec.size() > this->get_num_ddcs()){ -            throw std::runtime_error(str(boost::format( +            throw uhd::value_error(str(boost::format(                  "USRP1 suports up to %u RX channels.\n"                  "However, this RX subdev spec requires %u channels\n"              ) % this->get_num_ddcs() % _rx_subdev_spec.size())); @@ -362,7 +356,7 @@ void usrp1_impl::mboard_set(const wax::obj &key, const wax::obj &val)      case MBOARD_PROP_TX_SUBDEV_SPEC:          _tx_subdev_spec = val.as<subdev_spec_t>();          if (_tx_subdev_spec.size() > this->get_num_ducs()){ -            throw std::runtime_error(str(boost::format( +            throw uhd::value_error(str(boost::format(                  "USRP1 suports up to %u TX channels.\n"                  "However, this TX subdev spec requires %u channels\n"              ) % this->get_num_ducs() % _tx_subdev_spec.size())); diff --git a/host/lib/usrp/usrp1/usrp1_ctrl.cpp b/host/lib/usrp/usrp1/usrp1_ctrl.cpp index 09f854813..3fa6cb8b7 100644 --- a/host/lib/usrp/usrp1/usrp1_ctrl.cpp +++ b/host/lib/usrp/usrp1/usrp1_ctrl.cpp @@ -16,7 +16,8 @@  //  #include "usrp1_ctrl.hpp" -#include "usrp_commands.h"  +#include "usrp_commands.h" +#include <uhd/exception.hpp>  #include <uhd/transport/usb_control.hpp>  #include <boost/functional/hash.hpp>  #include <boost/thread/thread.hpp> @@ -29,13 +30,6 @@  using namespace uhd; -enum firmware_code { -    USRP_FPGA_LOAD_SUCCESS, -    USRP_FPGA_ALREADY_LOADED, -    USRP_FIRMWARE_LOAD_SUCCESS, -    USRP_FIRMWARE_ALREADY_LOADED -}; -  #define FX2_FIRMWARE_LOAD 0xa0  static const bool load_img_msg = true; @@ -45,15 +39,16 @@ static const bool load_img_msg = true;   **********************************************************************/  /*!   * Create a file hash - * The hash will be used to identify the loaded firmware and fpga image  + * The hash will be used to identify the loaded firmware and fpga image   * \param filename file used to generate hash value   * \return hash value in a size_t type   */  static size_t generate_hash(const char *filename)  {      std::ifstream file(filename); -    if (!file) -        std::cerr << "error: cannot open input file " << filename << std::endl; +    if (not file){ +        throw uhd::io_error(std::string("cannot open input file ") + filename); +    }      size_t hash = 0; @@ -62,18 +57,19 @@ static size_t generate_hash(const char *filename)          boost::hash_combine(hash, ch);      } -    if (!file.eof()) -        std::cerr << "error: file error " << filename << std::endl; +    if (not file.eof()){ +        throw uhd::io_error(std::string("file error ") + filename); +    } -    file.close();  -    return hash;  +    file.close(); +    return hash;  }  /*! - * Verify checksum of a Intel HEX record  + * Verify checksum of a Intel HEX record   * \param record a line from an Intel HEX file - * \return true if record is valid, false otherwise  + * \return true if record is valid, false otherwise   */  static bool checksum(std::string *record)  { @@ -123,7 +119,7 @@ bool parse_record(std::string *record, unsigned int &len,      for (i = 0; i < len; i++) {          std::istringstream(record->substr(9 + 2 * i, 2)) >> std::hex >> val;          data[i] = (unsigned char) val; -    }  +    }      return true;  } @@ -139,20 +135,15 @@ public:          _ctrl_transport = ctrl_transport;      } -    int usrp_load_firmware(std::string filestring, bool force) +    void usrp_load_firmware(std::string filestring, bool force)      {          const char *filename = filestring.c_str();          size_t hash = generate_hash(filename); -        size_t loaded_hash; -        if (usrp_get_firmware_hash(loaded_hash) < 0) { -            std::cerr << "firmware hash retrieval failed" << std::endl; -            return -1; -        } +        size_t loaded_hash; usrp_get_firmware_hash(loaded_hash); -        if (!force && (hash == loaded_hash)) -            return USRP_FIRMWARE_ALREADY_LOADED; +        if (not force and (hash == loaded_hash)) return;          //FIXME: verify types          unsigned int len; @@ -160,13 +151,11 @@ public:          unsigned int type;          unsigned char data[512]; -        int ret;          std::ifstream file;          file.open(filename, std::ifstream::in);          if (!file.good()) { -            std::cerr << "cannot open firmware input file" << std::endl; -            return -1;  +            throw uhd::io_error("usrp_load_firmware: cannot open firmware input file");          }          unsigned char reset_y = 1; @@ -174,56 +163,41 @@ public:          //hit the reset line          if (load_img_msg) std::cout << "Loading firmware image: " << filestring << "..." << std::flush; -        usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0, -                           &reset_y, 1); -  +        usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0, &reset_y, 1); +          while (!file.eof()) {             std::string record;             file >> record; -       -            //check for valid record  -            if (!checksum(&record) ||  -                    !parse_record(&record, len, addr, type, data)) { -                std::cerr << "error: bad record" << std::endl; -                file.close(); -                return -1; + +            //check for valid record +            if (not checksum(&record) or not parse_record(&record, len, addr, type, data)) { +                throw uhd::io_error("usrp_load_firmware: bad record checksum");              }              //type 0x00 is data              if (type == 0x00) { -               ret = usrp_control_write(FX2_FIRMWARE_LOAD, addr, 0, -                                        data, len); -               if (ret < 0) { -                    std::cerr << "error: usrp_control_write failed: "; -                    std::cerr << ret << std::endl; -                    file.close(); -                    return -1;  -                } -            }   -            //type 0x01 is end  +                int ret = usrp_control_write(FX2_FIRMWARE_LOAD, addr, 0, data, len); +                if (ret < 0) throw uhd::io_error("usrp_load_firmware: usrp_control_write failed"); +            } +            //type 0x01 is end              else if (type == 0x01) {                  usrp_set_firmware_hash(hash); //set hash before reset -                usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0, -                                   &reset_n, 1); +                usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0, &reset_n, 1);                  file.close();                  //wait for things to settle                  boost::this_thread::sleep(boost::posix_time::milliseconds(1000));                  if (load_img_msg) std::cout << " done" << std::endl; -                return USRP_FIRMWARE_LOAD_SUCCESS;  +                return;              }              //type anything else is unhandled              else { -                std::cerr << "error: unsupported record" << std::endl; -                file.close(); -                return -1;  +                throw uhd::io_error("usrp_load_firmware: unsupported record");              }          } -        //file did not end  -        std::cerr << "error: bad record" << std::endl; -        file.close(); -        return -1; +        //file did not end +        throw uhd::io_error("usrp_load_firmware: bad record");      }      void usrp_init(void){ @@ -241,64 +215,48 @@ public:          usrp_tx_enable(true);      } -    int usrp_load_fpga(std::string filestring) +    void usrp_load_fpga(std::string filestring)      {          const char *filename = filestring.c_str();          size_t hash = generate_hash(filename); -        size_t loaded_hash; -        if (usrp_get_fpga_hash(loaded_hash) < 0) { -            std::cerr << "fpga hash retrieval failed" << std::endl; -            return -1; -        } +        size_t loaded_hash; usrp_get_fpga_hash(loaded_hash); -        if (hash == loaded_hash) -            return USRP_FPGA_ALREADY_LOADED; +        if (hash == loaded_hash) return;          const int ep0_size = 64;          unsigned char buf[ep0_size]; -        int ret;          if (load_img_msg) std::cout << "Loading FPGA image: " << filestring << "..." << std::flush;          std::ifstream file;          file.open(filename, std::ios::in | std::ios::binary);          if (not file.good()) { -            std::cerr << "cannot open fpga input file" << std::endl; -            file.close(); -            return -1; +            throw uhd::io_error("usrp_load_fpga: cannot open fpga input file");          }          if (usrp_control_write_cmd(VRQ_FPGA_LOAD, 0, FL_BEGIN) < 0) { -            std::cerr << "fpga load error" << std::endl; -            file.close(); -            return -1; +            throw uhd::io_error("usrp_load_fpga: fpga load error");          }          while (not file.eof()) {              file.read((char *)buf, sizeof(buf));              size_t n = file.gcount(); -            ret = usrp_control_write(VRQ_FPGA_LOAD, 0, FL_XFER, -                                     buf, n); +            int ret = usrp_control_write(VRQ_FPGA_LOAD, 0, FL_XFER, buf, n);              if (ret < 0 or size_t(ret) != n) { -                std::cerr << "fpga load error " << ret << std::endl; -                file.close(); -                return -1; +                throw uhd::io_error("usrp_load_fpga: fpga load error");              }          } -  +          if (usrp_control_write_cmd(VRQ_FPGA_LOAD, 0, FL_END) < 0) { -            std::cerr << "fpga load error" << std::endl; -            file.close(); -            return -1; +            throw uhd::io_error("usrp_load_fpga: fpga load error");          }          usrp_set_fpga_hash(hash);          file.close();          if (load_img_msg) std::cout << " done" << std::endl; -        return 0;      } -    int usrp_load_eeprom(std::string filestring) +    void usrp_load_eeprom(std::string filestring)      {          const char *filename = filestring.c_str();          const boost::uint16_t i2c_addr = 0x50; @@ -309,100 +267,92 @@ public:          unsigned char data[256];          unsigned char sendbuf[17]; -        int ret;          std::ifstream file;          file.open(filename, std::ifstream::in); -        if (!file.good()) { -            std::cerr << "cannot open EEPROM input file" << std::endl; -            return -1;  +        if (not file.good()) { +            throw uhd::io_error("usrp_load_eeprom: cannot open EEPROM input file");          }          file.read((char *)data, 256);          len = file.gcount();          if(len == 256) { -          std::cerr << "error: image size too large" << std::endl; -          file.close(); -          return -1; +            throw uhd::io_error("usrp_load_eeprom: image size too large");          }          const int pagesize = 16;          addr = 0;          while(len > 0) { -          sendbuf[0] = addr; -          memcpy(sendbuf+1, &data[addr], len > pagesize ? pagesize : len); -          ret = usrp_i2c_write(i2c_addr, sendbuf, (len > pagesize ? pagesize : len)+1); -          if (ret < 0) { -            std::cerr << "error: usrp_i2c_write failed: "; -            std::cerr << ret << std::endl; -            file.close(); -            return -1;  -          } -          addr += pagesize; -          len -= pagesize; -          boost::this_thread::sleep(boost::posix_time::milliseconds(100)); +            sendbuf[0] = addr; +            memcpy(sendbuf+1, &data[addr], len > pagesize ? pagesize : len); +            int ret = usrp_i2c_write(i2c_addr, sendbuf, (len > pagesize ? pagesize : len)+1); +            if (ret < 0) { +                throw uhd::io_error("usrp_load_eeprom: usrp_i2c_write failed"); +            } +            addr += pagesize; +            len -= pagesize; +            boost::this_thread::sleep(boost::posix_time::milliseconds(100));          }          file.close(); -        return 0;      } -    int usrp_set_led(int led_num, bool on) +    void usrp_set_led(int led_num, bool on)      { -        return usrp_control_write_cmd(VRQ_SET_LED, on, led_num); +        UHD_ASSERT_THROW(usrp_control_write_cmd(VRQ_SET_LED, on, led_num) >= 0);      } -    int usrp_get_firmware_hash(size_t &hash) +    void usrp_get_firmware_hash(size_t &hash)      { -        return usrp_control_read(0xa0, USRP_HASH_SLOT_0_ADDR, 0,  -                                 (unsigned char*) &hash, sizeof(size_t)); +        UHD_ASSERT_THROW(usrp_control_read(0xa0, USRP_HASH_SLOT_0_ADDR, 0, +                                 (unsigned char*) &hash, sizeof(size_t)) >= 0);      } -    int usrp_set_firmware_hash(size_t hash) +    void usrp_set_firmware_hash(size_t hash)      { -        return usrp_control_write(0xa0, USRP_HASH_SLOT_0_ADDR, 0, -                                  (unsigned char*) &hash, sizeof(size_t)); +        UHD_ASSERT_THROW(usrp_control_write(0xa0, USRP_HASH_SLOT_0_ADDR, 0, +                                  (unsigned char*) &hash, sizeof(size_t)) >= 0);      } -    int usrp_get_fpga_hash(size_t &hash) +    void usrp_get_fpga_hash(size_t &hash)      { -        return usrp_control_read(0xa0, USRP_HASH_SLOT_1_ADDR, 0, -                                 (unsigned char*) &hash, sizeof(size_t)); +        UHD_ASSERT_THROW(usrp_control_read(0xa0, USRP_HASH_SLOT_1_ADDR, 0, +                                 (unsigned char*) &hash, sizeof(size_t)) >= 0);      } -    int usrp_set_fpga_hash(size_t hash) +    void usrp_set_fpga_hash(size_t hash)      { -        return usrp_control_write(0xa0, USRP_HASH_SLOT_1_ADDR, 0, -                                  (unsigned char*) &hash, sizeof(size_t)); +        UHD_ASSERT_THROW(usrp_control_write(0xa0, USRP_HASH_SLOT_1_ADDR, 0, +                                  (unsigned char*) &hash, sizeof(size_t)) >= 0);      } -    int usrp_tx_enable(bool on) +    void usrp_tx_enable(bool on)      { -        return usrp_control_write_cmd(VRQ_FPGA_SET_TX_ENABLE, on, 0); +        UHD_ASSERT_THROW(usrp_control_write_cmd(VRQ_FPGA_SET_TX_ENABLE, on, 0) >= 0);      } -    int usrp_rx_enable(bool on) +    void usrp_rx_enable(bool on)      { -        return usrp_control_write_cmd(VRQ_FPGA_SET_RX_ENABLE, on, 0);  +        UHD_ASSERT_THROW(usrp_control_write_cmd(VRQ_FPGA_SET_RX_ENABLE, on, 0) >= 0);      } -    int usrp_tx_reset(bool on) +    void usrp_tx_reset(bool on)      { -        return usrp_control_write_cmd(VRQ_FPGA_SET_TX_RESET, on, 0);  +        UHD_ASSERT_THROW(usrp_control_write_cmd(VRQ_FPGA_SET_TX_RESET, on, 0) >= 0);      } -    int usrp_rx_reset(bool on) +    void usrp_rx_reset(bool on)      { -        return usrp_control_write_cmd(VRQ_FPGA_SET_RX_RESET, on, 0);  +        UHD_ASSERT_THROW(usrp_control_write_cmd(VRQ_FPGA_SET_RX_RESET, on, 0) >= 0);      } @@ -417,7 +367,7 @@ public:                                         value,              // wValue                                         index,              // wIndex                                         buff,               // data -                                       length);            // wLength  +                                       length);            // wLength      } diff --git a/host/lib/usrp/usrp1/usrp1_ctrl.hpp b/host/lib/usrp/usrp1/usrp1_ctrl.hpp index 8ccfacab7..ee68f8401 100644 --- a/host/lib/usrp/usrp1/usrp1_ctrl.hpp +++ b/host/lib/usrp/usrp1/usrp1_ctrl.hpp @@ -40,60 +40,21 @@ public:       * Load firmware in Intel HEX Format onto device        * \param filename name of firmware file       * \param force reload firmware if already loaded -     * \return 0 on success, error code otherwise       */ -    virtual int usrp_load_firmware(std::string filename, +    virtual void usrp_load_firmware(std::string filename,                                     bool force = false) = 0;      /*!       * Load fpga file onto usrp        * \param filename name of fpga image  -     * \return 0 on success, error code otherwise       */ -    virtual int usrp_load_fpga(std::string filename) = 0; +    virtual void usrp_load_fpga(std::string filename) = 0;      /*!       * Load USB descriptor file in Intel HEX format into EEPROM -     * \param filename name of EEPROM image  -     * \return 0 on success, error code otherwise +     * \param filename name of EEPROM image       */ -    virtual int usrp_load_eeprom(std::string filestring) = 0; - -    /*! -     * Set led usrp  -     * \param led_num which LED to control (0 or 1) -     * \param on turn LED on or off -     * \return 0 on success, error code otherwise -     */ -    virtual int usrp_set_led(int led_num, bool on) = 0; - -    /*! -     * Get firmware hash  -     * \param hash a size_t hash value -     * \return 0 on success, error code otherwise -     */ -    virtual int usrp_get_firmware_hash(size_t &hash) = 0; - -    /*! -     * Set firmware hash  -     * \param hash a size_t hash value -     * \return 0 on success, error code otherwise -     */ -    virtual int usrp_set_firmware_hash(size_t hash) = 0; -                               -    /*! -     * Get fpga hash  -     * \param hash a size_t hash value -     * \return 0 on success, error code otherwise -     */ -    virtual int usrp_get_fpga_hash(size_t &hash) = 0; - -    /*! -     * Set fpga hash  -     * \param hash a size_t hash value -     * \return 0 on success, error code otherwise -     */ -    virtual int usrp_set_fpga_hash(size_t hash) = 0; +    virtual void usrp_load_eeprom(std::string filestring) = 0;      /*!       * Submit an IN transfer  diff --git a/host/lib/usrp/usrp1/usrp1_iface.cpp b/host/lib/usrp/usrp1/usrp1_iface.cpp index 63fcd5777..0c37610ce 100644 --- a/host/lib/usrp/usrp1/usrp1_iface.cpp +++ b/host/lib/usrp/usrp1/usrp1_iface.cpp @@ -17,7 +17,7 @@  #include "usrp1_iface.hpp"  #include "usrp_commands.h" -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp>  #include <uhd/utils/byteswap.hpp>  #include <boost/format.hpp>  #include <stdexcept> @@ -70,8 +70,7 @@ public:                                            (unsigned char*) &swapped,                                            sizeof(boost::uint32_t)); -        if (ret < 0) -            std::cerr << "USRP: failed memory write: " << ret << std::endl; +        if (ret < 0) throw uhd::io_error("USRP1: failed control write");      }      boost::uint32_t peek32(boost::uint32_t addr) @@ -88,11 +87,27 @@ public:                                            (unsigned char*) &value_out,                                            sizeof(boost::uint32_t)); -        if (ret < 0) -            std::cerr << "USRP: failed memory read: " << ret << std::endl; +        if (ret < 0) throw uhd::io_error("USRP1: failed control read");          return uhd::ntohx(value_out);      } +     +    void poke16(boost::uint32_t, boost::uint16_t) { +        throw uhd::not_implemented_error("Unhandled command poke16()"); +    } +     +    boost::uint16_t peek16(boost::uint32_t) { +        throw uhd::not_implemented_error("Unhandled command peek16()"); +        return 0; +    } +     +    void write_uart(boost::uint8_t, const std::string &) { +        throw uhd::not_implemented_error("Unhandled command write_uart()"); +    } +     +    std::string read_uart(boost::uint8_t) { +        throw uhd::not_implemented_error("Unhandled command read_uart()"); +    }      /*******************************************************************       * I2C @@ -176,10 +191,7 @@ public:                                           buff,                                           (w_len_h << 8) | (w_len_l << 0)); -            if (ret < 0) { -                std::cout << "USRP: failed SPI readback transaction: " -                          << std::dec << ret << std::endl; -            } +            if (ret < 0) throw uhd::io_error("USRP1: failed SPI readback transaction");              boost::uint32_t val = (((boost::uint32_t)buff[0]) <<  0) |                                    (((boost::uint32_t)buff[1]) <<  8) | @@ -197,10 +209,7 @@ public:                                            (w_index_h << 8) | (w_index_l << 0),                                            buff, num_bytes); -            if (ret < 0) { -                std::cout << "USRP: failed SPI transaction: " -                          << std::dec << ret << std::endl; -            } +            if (ret < 0) throw uhd::io_error("USRP1: failed SPI transaction");              return 0;          } @@ -234,8 +243,7 @@ public:                                                        length);          } -        if (ret < 0) -            std::cerr << "USRP: failed firmware command: " << ret << std::endl; +        if (ret < 0) throw uhd::io_error("USRP1: failed firmware command");      }  private: diff --git a/host/lib/usrp/usrp1/usrp1_iface.hpp b/host/lib/usrp/usrp1/usrp1_iface.hpp index 34a2330b5..fdb7464ce 100644 --- a/host/lib/usrp/usrp1/usrp1_iface.hpp +++ b/host/lib/usrp/usrp1/usrp1_iface.hpp @@ -18,8 +18,7 @@  #ifndef INCLUDED_USRP1_IFACE_HPP  #define INCLUDED_USRP1_IFACE_HPP -#include <uhd/usrp/mboard_eeprom.hpp> -#include <uhd/types/serial.hpp> +#include <uhd/usrp/mboard_iface.hpp>  #include <boost/shared_ptr.hpp>  #include <boost/utility.hpp>  #include "usrp1_ctrl.hpp" @@ -29,10 +28,13 @@   * Provides a set of functions to implementation layer.   * Including spi, peek, poke, control...   */ -class usrp1_iface : boost::noncopyable, public uhd::i2c_iface{ +class usrp1_iface : public uhd::usrp::mboard_iface, boost::noncopyable{  public:      typedef boost::shared_ptr<usrp1_iface> sptr; +    //motherboard eeprom map structure +    uhd::usrp::mboard_eeprom_t mb_eeprom; +      /*!       * Make a new usrp1 interface with the control transport.       * \param ctrl_transport the usrp controller object @@ -41,35 +43,6 @@ public:      static sptr make(usrp_ctrl::sptr ctrl_transport);      /*! -     * Write a register (32 bits) -     * \param addr the address -     * \param data the 32bit data -     */ -    virtual void poke32(boost::uint32_t addr, boost::uint32_t data) = 0; - -    /*! -     * Read a register (32 bits) -     * \param addr the address -     * \return the 32bit data -     */ -    virtual boost::uint32_t peek32(boost::uint32_t addr) = 0; - -    /*! -     * Perform an spi transaction. -     * \param which_slave the slave device number -     * \param config spi config args -     * \param data the bits to write -     * \param num_bits how many bits in data -     * \param readback true to readback a value -     * \return spi data if readback set -     */ -    virtual boost::uint32_t transact_spi(int which_slave, -                                         const uhd::spi_config_t &config, -                                         boost::uint32_t data, -                                         size_t num_bits, -                                         bool readback) = 0; - -    /*!       * Perform a general USB firmware OUT operation       * \param request        * \param value @@ -82,8 +55,6 @@ public:                                     boost::uint16_t index,                                     unsigned char* buff,                                     boost::uint16_t length) = 0; - -    uhd::usrp::mboard_eeprom_t mb_eeprom;  };  #endif /* INCLUDED_USRP1_IFACE_HPP */ diff --git a/host/lib/usrp/usrp1/usrp1_impl.cpp b/host/lib/usrp/usrp1/usrp1_impl.cpp index 918032037..7005c59f2 100644 --- a/host/lib/usrp/usrp1/usrp1_impl.cpp +++ b/host/lib/usrp/usrp1/usrp1_impl.cpp @@ -19,11 +19,12 @@  #include "usrp1_ctrl.hpp"  #include "fpga_regs_standard.h"  #include "usrp_spi_defs.h" +#include <uhd/utils/safe_call.hpp>  #include <uhd/transport/usb_control.hpp>  #include <uhd/usrp/device_props.hpp>  #include <uhd/usrp/mboard_props.hpp>  #include <uhd/utils/warning.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp>  #include <uhd/utils/static.hpp>  #include <uhd/utils/images.hpp>  #include <boost/format.hpp> @@ -199,7 +200,16 @@ usrp1_impl::usrp1_impl(uhd::transport::usb_zero_copy::sptr data_transport,  }  usrp1_impl::~usrp1_impl(void){ -    /* NOP */ +    //Safely destruct all RAII objects in a device. +    //This prevents the mboard deconstructor from throwing, +    //which allows the device to be safely deconstructed. +    BOOST_FOREACH(dboard_slot_t slot, _dboard_slots){ +        UHD_SAFE_CALL(_dboard_managers[slot].reset();) +        UHD_SAFE_CALL(_dboard_ifaces[slot].reset();) +        UHD_SAFE_CALL(_codec_ctrls[slot].reset();) +    } +    UHD_SAFE_CALL(_clock_ctrl.reset();) +    UHD_SAFE_CALL(_io_impl.reset();)  }  bool usrp1_impl::recv_async_msg(uhd::async_metadata_t &, double timeout){ diff --git a/host/lib/usrp/usrp1/usrp1_impl.hpp b/host/lib/usrp/usrp1/usrp1_impl.hpp index 1d9f6709f..9755c466d 100644 --- a/host/lib/usrp/usrp1/usrp1_impl.hpp +++ b/host/lib/usrp/usrp1/usrp1_impl.hpp @@ -182,19 +182,19 @@ private:      //rx dsp functions and settings      void rx_dsp_init(void); -    void rx_dsp_get(const wax::obj &, wax::obj &); -    void rx_dsp_set(const wax::obj &, const wax::obj &); -    uhd::dict<std::string, double> _rx_dsp_freqs; +    void rx_dsp_get(const wax::obj &, wax::obj &, size_t); +    void rx_dsp_set(const wax::obj &, const wax::obj &, size_t); +    uhd::dict<size_t, double> _rx_dsp_freqs;      size_t _rx_dsp_decim; -    wax_obj_proxy::sptr _rx_dsp_proxy; +    uhd::dict<std::string, wax_obj_proxy::sptr> _rx_dsp_proxies;      //tx dsp functions and settings      void tx_dsp_init(void); -    void tx_dsp_get(const wax::obj &, wax::obj &); -    void tx_dsp_set(const wax::obj &, const wax::obj &); -    uhd::dict<std::string, double> _tx_dsp_freqs; +    void tx_dsp_get(const wax::obj &, wax::obj &, size_t); +    void tx_dsp_set(const wax::obj &, const wax::obj &, size_t); +    uhd::dict<size_t, double> _tx_dsp_freqs;      size_t _tx_dsp_interp; -    wax_obj_proxy::sptr _tx_dsp_proxy; +    uhd::dict<std::string, wax_obj_proxy::sptr> _tx_dsp_proxies;      //transports      uhd::transport::usb_zero_copy::sptr _data_transport; diff --git a/host/lib/usrp/usrp2/clock_ctrl.cpp b/host/lib/usrp/usrp2/clock_ctrl.cpp index 27ccefb2b..abda53bf2 100644 --- a/host/lib/usrp/usrp2/clock_ctrl.cpp +++ b/host/lib/usrp/usrp2/clock_ctrl.cpp @@ -19,7 +19,7 @@  #include "ad9510_regs.hpp"  #include "usrp2_regs.hpp" //spi slave constants  #include "usrp2_clk_regs.hpp" -#include <uhd/utils/assert.hpp> +#include <uhd/utils/assert_has.hpp>  #include <boost/cstdint.hpp>  #include <boost/lexical_cast.hpp>  #include <boost/math/special_functions/round.hpp> @@ -305,7 +305,7 @@ private:       */      void write_reg(boost::uint8_t addr){          boost::uint32_t data = _ad9510_regs.get_write_reg(addr); -        _iface->transact_spi(SPI_SS_AD9510, spi_config_t::EDGE_RISE, data, 24, false /*no rb*/); +        _iface->write_spi(SPI_SS_AD9510, spi_config_t::EDGE_RISE, data, 24);      }      /*! diff --git a/host/lib/usrp/usrp2/codec_ctrl.cpp b/host/lib/usrp/usrp2/codec_ctrl.cpp index 890969b5a..0fdcedf62 100644 --- a/host/lib/usrp/usrp2/codec_ctrl.cpp +++ b/host/lib/usrp/usrp2/codec_ctrl.cpp @@ -19,10 +19,10 @@  #include "ad9777_regs.hpp"  #include "ads62p44_regs.hpp"  #include "usrp2_regs.hpp" +#include <uhd/exception.hpp>  #include <boost/cstdint.hpp>  #include <boost/foreach.hpp>  #include <iostream> -#include <uhd/utils/exception.hpp>  static const bool codec_ctrl_debug = false; @@ -118,7 +118,7 @@ public:          case 2: _ad9777_regs.modulation_mode = ad9777_regs_t::MODULATION_MODE_FS_2; break;          case 4: _ad9777_regs.modulation_mode = ad9777_regs_t::MODULATION_MODE_FS_4; break;          case 8: _ad9777_regs.modulation_mode = ad9777_regs_t::MODULATION_MODE_FS_8; break; -        default: throw std::runtime_error("unknown modulation mode for ad9777"); +        default: throw uhd::value_error("unknown modulation mode for ad9777");          }          this->send_ad9777_reg(0x01); //set the register @@ -168,17 +168,17 @@ private:      void send_ad9777_reg(boost::uint8_t addr){          boost::uint16_t reg = _ad9777_regs.get_write_reg(addr);          if (codec_ctrl_debug) std::cout << "send_ad9777_reg: " << std::hex << reg << std::endl; -        _iface->transact_spi( +        _iface->write_spi(              SPI_SS_AD9777, spi_config_t::EDGE_RISE, -            reg, 16, false /*no rb*/ +            reg, 16          );      }      void send_ads62p44_reg(boost::uint8_t addr) {          boost::uint16_t reg = _ads62p44_regs.get_write_reg(addr); -        _iface->transact_spi( +        _iface->write_spi(              SPI_SS_ADS62P44, spi_config_t::EDGE_FALL, -            reg, 16, false /*no rb*/ +            reg, 16          );      }  }; diff --git a/host/lib/usrp/usrp2/codec_impl.cpp b/host/lib/usrp/usrp2/codec_impl.cpp index 09bec6db2..50320773f 100644 --- a/host/lib/usrp/usrp2/codec_impl.cpp +++ b/host/lib/usrp/usrp2/codec_impl.cpp @@ -16,13 +16,13 @@  //  #include "usrp2_impl.hpp" +#include <uhd/utils/assert_has.hpp> +#include <uhd/exception.hpp>  #include <uhd/usrp/codec_props.hpp>  #include <uhd/types/dict.hpp>  #include <uhd/types/ranges.hpp>  #include <boost/bind.hpp>  #include <boost/assign/list_of.hpp> -#include <uhd/utils/assert.hpp> -#include <uhd/utils/exception.hpp>  using namespace uhd;  using namespace uhd::usrp; diff --git a/host/lib/usrp/usrp2/dboard_iface.cpp b/host/lib/usrp/usrp2/dboard_iface.cpp index c539b0058..924a6e901 100644 --- a/host/lib/usrp/usrp2/dboard_iface.cpp +++ b/host/lib/usrp/usrp2/dboard_iface.cpp @@ -20,7 +20,7 @@  #include "usrp2_regs.hpp" //wishbone address constants  #include <uhd/usrp/dboard_iface.hpp>  #include <uhd/types/dict.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp>  #include <uhd/utils/algorithm.hpp>  #include <boost/assign/list_of.hpp>  #include <boost/asio.hpp> //htonl and ntohl @@ -257,7 +257,7 @@ void usrp2_dboard_iface::write_spi(      boost::uint32_t data,      size_t num_bits  ){ -    _iface->transact_spi(unit_to_spi_dev[unit], config, data, num_bits, false /*no rb*/); +    _iface->write_spi(unit_to_spi_dev[unit], config, data, num_bits);  }  boost::uint32_t usrp2_dboard_iface::read_write_spi( @@ -266,7 +266,7 @@ boost::uint32_t usrp2_dboard_iface::read_write_spi(      boost::uint32_t data,      size_t num_bits  ){ -    return _iface->transact_spi(unit_to_spi_dev[unit], config, data, num_bits, true /*rb*/); +    return _iface->read_spi(unit_to_spi_dev[unit], config, data, num_bits);  }  /*********************************************************************** @@ -288,9 +288,9 @@ void usrp2_dboard_iface::_write_aux_dac(unit_t unit){          (UNIT_RX, SPI_SS_RX_DAC)          (UNIT_TX, SPI_SS_TX_DAC)      ; -    _iface->transact_spi( +    _iface->write_spi(          unit_to_spi_dac[unit], spi_config_t::EDGE_FALL,  -        _dac_regs[unit].get_reg(), 24, false /*no rb*/ +        _dac_regs[unit].get_reg(), 24      );  } @@ -336,13 +336,13 @@ double usrp2_dboard_iface::read_aux_adc(unit_t unit, aux_adc_t which){      } ad7922_regs.chn = ad7922_regs.mod; //normal mode: mod == chn      //write and read spi -    _iface->transact_spi( +    _iface->write_spi(          unit_to_spi_adc[unit], config, -        ad7922_regs.get_reg(), 16, false /*no rb*/ +        ad7922_regs.get_reg(), 16      ); -    ad7922_regs.set_reg(boost::uint16_t(_iface->transact_spi( +    ad7922_regs.set_reg(boost::uint16_t(_iface->read_spi(          unit_to_spi_adc[unit], config, -        ad7922_regs.get_reg(), 16, true /*rb*/ +        ad7922_regs.get_reg(), 16      )));      //convert to voltage and return diff --git a/host/lib/usrp/usrp2/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp index 4f1dcc46b..3f41cddcf 100644 --- a/host/lib/usrp/usrp2/dboard_impl.cpp +++ b/host/lib/usrp/usrp2/dboard_impl.cpp @@ -22,7 +22,7 @@  #include <uhd/usrp/dsp_utils.hpp>  #include <uhd/usrp/subdev_props.hpp>  #include <uhd/usrp/dboard_props.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp>  #include <boost/format.hpp>  #include <boost/bind.hpp>  #include <boost/asio.hpp> //htonl and ntohl diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp index 8340f7cdd..cdd559e94 100644 --- a/host/lib/usrp/usrp2/dsp_impl.cpp +++ b/host/lib/usrp/usrp2/dsp_impl.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 @@ -28,12 +28,79 @@  using namespace uhd;  using namespace uhd::usrp; -static const size_t default_decim = 16; -static const size_t default_interp = 16; -  /*********************************************************************** - * DDC Helper Methods + * DSP impl and methods   **********************************************************************/ +struct usrp2_mboard_impl::dsp_impl{ +    uhd::dict<size_t, size_t> ddc_decim; +    uhd::dict<size_t, double> ddc_freq; +    uhd::dict<size_t, size_t> duc_interp; +    uhd::dict<size_t, double> duc_freq; +    std::vector<size_t> decim_and_interp_rates; +    uhd::dict<size_t, bool> continuous_streaming; +}; + +void usrp2_mboard_impl::dsp_init(void){ +    //create new dsp impl +    _dsp_impl = UHD_PIMPL_MAKE(dsp_impl, ()); + +    //load the allowed decim/interp rates +    //range(4, 128+1, 1) + range(130, 256+1, 2) + range(260, 512+1, 4) +    for (size_t i = 4; i <= 128; i+=1){ +        _dsp_impl->decim_and_interp_rates.push_back(i); +    } +    for (size_t i = 130; i <= 256; i+=2){ +        _dsp_impl->decim_and_interp_rates.push_back(i); +    } +    for (size_t i = 260; i <= 512; i+=4){ +        _dsp_impl->decim_and_interp_rates.push_back(i); +    } + +    //bind and initialize the rx dsps +    for (size_t i = 0; i < NUM_RX_DSPS; i++){ +        _rx_dsp_proxies[str(boost::format("DSP%d")%i)] = wax_obj_proxy::make( +            boost::bind(&usrp2_mboard_impl::ddc_get, this, _1, _2, i), +            boost::bind(&usrp2_mboard_impl::ddc_set, this, _1, _2, i) +        ); + +        //initial config and update +        ddc_set(DSP_PROP_FREQ_SHIFT, double(0), i); +        ddc_set(DSP_PROP_HOST_RATE, double(get_master_clock_freq()/16), i); + +        //setup the rx control registers +        _iface->poke32(_iface->regs.rx_ctrl[i].clear_overrun, 1); //reset +        _iface->poke32(_iface->regs.rx_ctrl[i].nsamps_per_pkt, _device.get_max_recv_samps_per_packet()); +        _iface->poke32(_iface->regs.rx_ctrl[i].nchannels, 1); +        _iface->poke32(_iface->regs.rx_ctrl[i].vrt_header, 0 +            | (0x1 << 28) //if data with stream id +            | (0x1 << 26) //has trailer +            | (0x3 << 22) //integer time other +            | (0x1 << 20) //fractional time sample count +        ); +        _iface->poke32(_iface->regs.rx_ctrl[i].vrt_stream_id, usrp2_impl::RECV_SID); +        _iface->poke32(_iface->regs.rx_ctrl[i].vrt_trailer, 0); +        _iface->poke32(_iface->regs.time64_tps, size_t(get_master_clock_freq())); +    } + +    //bind and initialize the tx dsps +    for (size_t i = 0; i < NUM_TX_DSPS; i++){ +        _tx_dsp_proxies[str(boost::format("DSP%d")%i)] = wax_obj_proxy::make( +            boost::bind(&usrp2_mboard_impl::duc_get, this, _1, _2, i), +            boost::bind(&usrp2_mboard_impl::duc_set, this, _1, _2, i) +        ); + +        //initial config and update +        duc_set(DSP_PROP_FREQ_SHIFT, double(0), i); +        duc_set(DSP_PROP_HOST_RATE, double(get_master_clock_freq()/16), i); + +        //init the tx control registers +        _iface->poke32(_iface->regs.tx_ctrl_clear_state, 1); //reset +        _iface->poke32(_iface->regs.tx_ctrl_num_chan, 0);    //1 channel +        _iface->poke32(_iface->regs.tx_ctrl_report_sid, usrp2_impl::ASYNC_SID); +        _iface->poke32(_iface->regs.tx_ctrl_policy, U2_FLAG_TX_CTRL_POLICY_NEXT_PACKET); +    } +} +  template <typename rate_type>  static rate_type pick_closest_rate(double exact_rate, const std::vector<rate_type> &rates){      unsigned closest_match = rates.front(); @@ -44,27 +111,28 @@ static rate_type pick_closest_rate(double exact_rate, const std::vector<rate_typ      return closest_match;  } -void usrp2_mboard_impl::init_ddc_config(void){ -    //create the ddc in the rx dsp dict -    _rx_dsp_proxy = wax_obj_proxy::make( -        boost::bind(&usrp2_mboard_impl::ddc_get, this, _1, _2), -        boost::bind(&usrp2_mboard_impl::ddc_set, this, _1, _2) -    ); +void usrp2_mboard_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd, size_t which_dsp){ +    _dsp_impl->continuous_streaming[which_dsp] = stream_cmd.stream_mode == stream_cmd_t::STREAM_MODE_START_CONTINUOUS; +    _iface->poke32(_iface->regs.rx_ctrl[which_dsp].stream_cmd, dsp_type1::calc_stream_cmd_word(stream_cmd)); +    _iface->poke32(_iface->regs.rx_ctrl[which_dsp].time_secs,  boost::uint32_t(stream_cmd.time_spec.get_full_secs())); +    _iface->poke32(_iface->regs.rx_ctrl[which_dsp].time_ticks, stream_cmd.time_spec.get_tick_count(get_master_clock_freq())); +} -    //initial config and update -    ddc_set(DSP_PROP_FREQ_SHIFT, double(0)); -    ddc_set(DSP_PROP_HOST_RATE, double(get_master_clock_freq()/default_decim)); +void usrp2_mboard_impl::handle_overflow(size_t which_dsp){ +    if (_dsp_impl->continuous_streaming[which_dsp]){ //re-issue the stream command if already continuous +        this->issue_ddc_stream_cmd(stream_cmd_t::STREAM_MODE_START_CONTINUOUS, which_dsp); +    }  }  /***********************************************************************   * DDC Properties   **********************************************************************/ -void usrp2_mboard_impl::ddc_get(const wax::obj &key_, wax::obj &val){ +void usrp2_mboard_impl::ddc_get(const wax::obj &key_, wax::obj &val, size_t which_dsp){      named_prop_t key = named_prop_t::extract(key_);      switch(key.as<dsp_prop_t>()){      case DSP_PROP_NAME: -        val = _iface->get_cname() + " ddc0"; +        val = str(boost::format("%s ddc%d") % _iface->get_cname() % which_dsp);          return;      case DSP_PROP_OTHERS: @@ -72,11 +140,7 @@ void usrp2_mboard_impl::ddc_get(const wax::obj &key_, wax::obj &val){          return;      case DSP_PROP_FREQ_SHIFT: -        val = _ddc_freq; -        return; - -    case DSP_PROP_FREQ_SHIFT_NAMES: -        val = prop_names_t(1, ""); +        val = _dsp_impl->ddc_freq[which_dsp];          return;      case DSP_PROP_CODEC_RATE: @@ -84,37 +148,41 @@ void usrp2_mboard_impl::ddc_get(const wax::obj &key_, wax::obj &val){          return;      case DSP_PROP_HOST_RATE: -        val = get_master_clock_freq()/_ddc_decim; +        val = get_master_clock_freq()/_dsp_impl->ddc_decim[which_dsp];          return;      default: UHD_THROW_PROP_GET_ERROR();      }  } -void usrp2_mboard_impl::ddc_set(const wax::obj &key_, const wax::obj &val){ +void usrp2_mboard_impl::ddc_set(const wax::obj &key_, const wax::obj &val, size_t which_dsp){      named_prop_t key = named_prop_t::extract(key_);      switch(key.as<dsp_prop_t>()){ +    case DSP_PROP_STREAM_CMD: +        issue_ddc_stream_cmd(val.as<stream_cmd_t>(), which_dsp); +        return; +      case DSP_PROP_FREQ_SHIFT:{              double new_freq = val.as<double>(); -            _iface->poke32(_iface->regs.dsp_rx_freq, +            _iface->poke32(_iface->regs.dsp_rx[which_dsp].freq,                  dsp_type1::calc_cordic_word_and_update(new_freq, get_master_clock_freq())              ); -            _ddc_freq = new_freq; //shadow +            _dsp_impl->ddc_freq[which_dsp] = new_freq; //shadow          }          return;      case DSP_PROP_HOST_RATE:{              double extact_rate = get_master_clock_freq()/val.as<double>(); -            _ddc_decim = pick_closest_rate(extact_rate, _allowed_decim_and_interp_rates); +            _dsp_impl->ddc_decim[which_dsp] = pick_closest_rate(extact_rate, _dsp_impl->decim_and_interp_rates);              //set the decimation -            _iface->poke32(_iface->regs.dsp_rx_decim_rate, dsp_type1::calc_cic_filter_word(_ddc_decim)); +            _iface->poke32(_iface->regs.dsp_rx[which_dsp].decim_rate, dsp_type1::calc_cic_filter_word(_dsp_impl->ddc_decim[which_dsp]));              //set the scaling              static const boost::int16_t default_rx_scale_iq = 1024; -            _iface->poke32(_iface->regs.dsp_rx_scale_iq, +            _iface->poke32(_iface->regs.dsp_rx[which_dsp].scale_iq,                  dsp_type1::calc_iq_scale_word(default_rx_scale_iq, default_rx_scale_iq)              );          } @@ -125,29 +193,14 @@ void usrp2_mboard_impl::ddc_set(const wax::obj &key_, const wax::obj &val){  }  /*********************************************************************** - * DUC Helper Methods - **********************************************************************/ -void usrp2_mboard_impl::init_duc_config(void){ -    //create the duc in the tx dsp dict -    _tx_dsp_proxy = wax_obj_proxy::make( -        boost::bind(&usrp2_mboard_impl::duc_get, this, _1, _2), -        boost::bind(&usrp2_mboard_impl::duc_set, this, _1, _2) -    ); - -    //initial config and update -    duc_set(DSP_PROP_FREQ_SHIFT, double(0)); -    duc_set(DSP_PROP_HOST_RATE, double(get_master_clock_freq()/default_interp)); -} - -/***********************************************************************   * DUC Properties   **********************************************************************/ -void usrp2_mboard_impl::duc_get(const wax::obj &key_, wax::obj &val){ +void usrp2_mboard_impl::duc_get(const wax::obj &key_, wax::obj &val, size_t which_dsp){      named_prop_t key = named_prop_t::extract(key_);      switch(key.as<dsp_prop_t>()){      case DSP_PROP_NAME: -        val = _iface->get_cname() + " duc0"; +        val = str(boost::format("%s duc%d") % _iface->get_cname() % which_dsp);          return;      case DSP_PROP_OTHERS: @@ -155,11 +208,7 @@ void usrp2_mboard_impl::duc_get(const wax::obj &key_, wax::obj &val){          return;      case DSP_PROP_FREQ_SHIFT: -        val = _duc_freq; -        return; - -    case DSP_PROP_FREQ_SHIFT_NAMES: -        val = prop_names_t(1, ""); +        val = _dsp_impl->duc_freq[which_dsp];          return;      case DSP_PROP_CODEC_RATE: @@ -167,14 +216,14 @@ void usrp2_mboard_impl::duc_get(const wax::obj &key_, wax::obj &val){          return;      case DSP_PROP_HOST_RATE: -        val = get_master_clock_freq()/_duc_interp; +        val = get_master_clock_freq()/_dsp_impl->duc_interp[which_dsp];          return;      default: UHD_THROW_PROP_GET_ERROR();      }  } -void usrp2_mboard_impl::duc_set(const wax::obj &key_, const wax::obj &val){ +void usrp2_mboard_impl::duc_set(const wax::obj &key_, const wax::obj &val, size_t which_dsp){      named_prop_t key = named_prop_t::extract(key_);      switch(key.as<dsp_prop_t>()){ @@ -196,19 +245,19 @@ void usrp2_mboard_impl::duc_set(const wax::obj &key_, const wax::obj &val){              _iface->poke32(_iface->regs.dsp_tx_freq,                  dsp_type1::calc_cordic_word_and_update(new_freq, codec_rate)              ); -            _duc_freq = new_freq + dac_shift; //shadow +            _dsp_impl->duc_freq[which_dsp] = new_freq + dac_shift; //shadow          }          return;      case DSP_PROP_HOST_RATE:{              double extact_rate = get_master_clock_freq()/val.as<double>(); -            _duc_interp = pick_closest_rate(extact_rate, _allowed_decim_and_interp_rates); +            _dsp_impl->duc_interp[which_dsp] = pick_closest_rate(extact_rate, _dsp_impl->decim_and_interp_rates);              //set the interpolation -            _iface->poke32(_iface->regs.dsp_tx_interp_rate, dsp_type1::calc_cic_filter_word(_duc_interp)); +            _iface->poke32(_iface->regs.dsp_tx_interp_rate, dsp_type1::calc_cic_filter_word(_dsp_impl->duc_interp[which_dsp]));              //set the scaling -            _iface->poke32(_iface->regs.dsp_tx_scale_iq, dsp_type1::calc_iq_scale_word(_duc_interp)); +            _iface->poke32(_iface->regs.dsp_tx_scale_iq, dsp_type1::calc_iq_scale_word(_dsp_impl->duc_interp[which_dsp]));          }          return; diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h index a22f805e1..68c49cafc 100644 --- a/host/lib/usrp/usrp2/fw_common.h +++ b/host/lib/usrp/usrp2/fw_common.h @@ -30,8 +30,8 @@ extern "C" {  #endif  //fpga and firmware compatibility numbers -#define USRP2_FPGA_COMPAT_NUM 4 -#define USRP2_FW_COMPAT_NUM 8 +#define USRP2_FPGA_COMPAT_NUM 5 +#define USRP2_FW_COMPAT_NUM 9  //used to differentiate control packets over data port  #define USRP2_INVALID_VRT_HEADER 0 @@ -40,8 +40,9 @@ extern "C" {  // Dynamic and/or private ports: 49152-65535  #define USRP2_UDP_CTRL_PORT 49152  //#define USRP2_UDP_UPDATE_PORT 49154 -#define USRP2_UDP_DATA_PORT 49156 +#define USRP2_UDP_DSP0_PORT 49156  #define USRP2_UDP_ERR0_PORT 49157 +#define USRP2_UDP_DSP1_PORT 49158  ////////////////////////////////////////////////////////////////////////  // I2C addresses @@ -88,6 +89,9 @@ typedef enum{      USRP2_CTRL_ID_SO_LIKE_CAN_YOU_READ_THIS_UART_BRO = 'v',      USRP2_CTRL_ID_I_HELLA_READ_THAT_UART_DUDE = 'V', +    USRP2_CTRL_ID_HOLLER_AT_ME_BRO = 'l', +    USRP2_CTRL_ID_HOLLER_BACK_DUDE = 'L', +      USRP2_CTRL_ID_PEACE_OUT = '~'  } usrp2_ctrl_id_t; @@ -132,6 +136,9 @@ typedef struct{              uint8_t bytes;              uint8_t data[20];          } uart_args; +        struct { +            uint32_t len; +        } echo_args;      } data;  } usrp2_ctrl_data_t; diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index a22482271..340e9d155 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -18,6 +18,8 @@  #include "../../transport/vrt_packet_handler.hpp"  #include "usrp2_impl.hpp"  #include "usrp2_regs.hpp" +#include <uhd/exception.hpp> +#include <uhd/usrp/mboard_props.hpp>  #include <uhd/utils/byteswap.hpp>  #include <uhd/utils/thread_priority.hpp>  #include <uhd/transport/bounded_buffer.hpp> @@ -136,27 +138,26 @@ private: size_t _indexes;   **********************************************************************/  struct usrp2_impl::io_impl{ -    io_impl(size_t send_frame_size, const std::vector<zero_copy_if::sptr> &xports): -        xports(xports), +    io_impl(std::vector<zero_copy_if::sptr> &dsp_xports): +        dsp_xports(dsp_xports), //the assumption is that all data transports should be identical          get_recv_buffs_fcn(boost::bind(&usrp2_impl::io_impl::get_recv_buffs, this, _1)),          get_send_buffs_fcn(boost::bind(&usrp2_impl::io_impl::get_send_buffs, this, _1)), -        packet_handler_recv_state(xports.size()), -        packet_handler_send_state(xports.size()),          async_msg_fifo(100/*messages deep*/)      { -        for (size_t i = 0; i < xports.size(); i++){ -            fc_mons.push_back(flow_control_monitor::sptr( -                new flow_control_monitor(usrp2_impl::sram_bytes/send_frame_size) -            )); -            //init empty packet infos -            vrt::if_packet_info_t packet_info; -            packet_info.packet_count = 0xf; -            packet_info.has_tsi = true; -            packet_info.tsi = 0; -            packet_info.has_tsf = true; -            packet_info.tsf = 0; -            prev_infos.push_back(packet_info); +        for (size_t i = 0; i < dsp_xports.size(); i++){ +            fc_mons.push_back(flow_control_monitor::sptr(new flow_control_monitor( +                usrp2_impl::sram_bytes/dsp_xports.front()->get_send_frame_size() +            )));;          } + +        //init empty packet infos +        vrt::if_packet_info_t packet_info = vrt::if_packet_info_t(); +        packet_info.packet_count = 0xf; +        packet_info.has_tsi = true; +        packet_info.tsi = 0; +        packet_info.has_tsf = true; +        packet_info.tsf = 0; +        prev_infos.resize(dsp_xports.size(), packet_info);      }      ~io_impl(void){ @@ -166,15 +167,15 @@ struct usrp2_impl::io_impl{      }      bool get_send_buffs(vrt_packet_handler::managed_send_buffs_t &buffs){ -        UHD_ASSERT_THROW(xports.size() == buffs.size()); +        UHD_ASSERT_THROW(send_map.size() == buffs.size());          //calculate the flow control word          const boost::uint32_t fc_word32 = packet_handler_send_state.next_packet_seq;          //grab a managed buffer for each index          for (size_t i = 0; i < buffs.size(); i++){ -            if (not fc_mons[i]->check_fc_condition(fc_word32, send_timeout)) return false; -            buffs[i] = xports[i]->get_send_buff(send_timeout); +            if (not fc_mons[send_map[i]]->check_fc_condition(fc_word32, send_timeout)) return false; +            buffs[i] = dsp_xports[send_map[i]]->get_send_buff(send_timeout);              if (not buffs[i].get()) return false;              buffs[i]->cast<boost::uint32_t *>()[0] = uhd::htonx(fc_word32);          } @@ -182,9 +183,13 @@ struct usrp2_impl::io_impl{      }      alignment_indexes indexes_to_do; //used in alignment logic +    time_spec_t expected_time; //used in alignment logic      bool get_recv_buffs(vrt_packet_handler::managed_recv_buffs_t &buffs); -    const std::vector<zero_copy_if::sptr> &xports; +    std::vector<zero_copy_if::sptr> &dsp_xports; + +    //mappings from channel index to dsp xport +    std::vector<size_t> send_map, recv_map;      //timeouts set on calls to recv/send (passed into get buffs methods)      double recv_timeout, send_timeout; @@ -204,7 +209,7 @@ struct usrp2_impl::io_impl{      vrt_packet_handler::send_state packet_handler_send_state;      //methods and variables for the pirate crew -    void recv_pirate_loop(zero_copy_if::sptr, usrp2_mboard_impl::sptr, size_t); +    void recv_pirate_loop(usrp2_mboard_impl::sptr, zero_copy_if::sptr, size_t);      boost::thread_group recv_pirate_crew;      bool recv_pirate_crew_raiding;      bounded_buffer<async_metadata_t> async_msg_fifo; @@ -218,17 +223,18 @@ struct usrp2_impl::io_impl{   * - put async message packets into queue   **********************************************************************/  void usrp2_impl::io_impl::recv_pirate_loop( -    zero_copy_if::sptr zc_if_err0, -    usrp2_mboard_impl::sptr mboard, -    size_t index +    usrp2_mboard_impl::sptr mboard, zero_copy_if::sptr err_xport, size_t index  ){      set_thread_priority_safe();      recv_pirate_crew_raiding = true;      spawn_mutex.unlock(); +    //store a reference to the flow control monitor (offset by max dsps) +    flow_control_monitor &fc_mon = *(this->fc_mons[index*usrp2_mboard_impl::MAX_NUM_DSPS]); +      while(recv_pirate_crew_raiding){ -        managed_recv_buffer::sptr buff = zc_if_err0->get_recv_buff(); +        managed_recv_buffer::sptr buff = err_xport->get_recv_buff();          if (not buff.get()) continue; //ignore timeout/error buffers          try{ @@ -253,7 +259,7 @@ void usrp2_impl::io_impl::recv_pirate_loop(                  //catch the flow control packets and react                  if (metadata.event_code == 0){                      boost::uint32_t fc_word32 = (vrt_hdr + if_packet_info.num_header_words32)[1]; -                    this->fc_mons[index]->update_fc_condition(uhd::ntohx(fc_word32)); +                    fc_mon.update_fc_condition(uhd::ntohx(fc_word32));                      continue;                  } @@ -276,27 +282,52 @@ void usrp2_impl::io_impl::recv_pirate_loop(   **********************************************************************/  void usrp2_impl::io_init(void){ -    //the assumption is that all data transports should be identical -    const size_t send_frame_size = _data_transports.front()->get_send_frame_size(); -      //create new io impl -    _io_impl = UHD_PIMPL_MAKE(io_impl, (send_frame_size, _data_transports)); +    _io_impl = UHD_PIMPL_MAKE(io_impl, (dsp_xports));      //create a new pirate thread for each zc if (yarr!!) -    for (size_t i = 0; i < _data_transports.size(); i++){ +    for (size_t i = 0; i < _mboards.size(); i++){          //lock the unlocked mutex (non-blocking)          _io_impl->spawn_mutex.lock();          //spawn a new pirate to plunder the recv booty          _io_impl->recv_pirate_crew.create_thread(boost::bind(              &usrp2_impl::io_impl::recv_pirate_loop, -            _io_impl.get(), _err0_transports.at(i), -            _mboards.at(i), i +            _io_impl.get(), _mboards.at(i), err_xports.at(i), i          ));          //block here until the spawned thread unlocks          _io_impl->spawn_mutex.lock();          //exit loop iteration in an unlocked condition          _io_impl->spawn_mutex.unlock();      } + +    //update mapping here since it didnt b4 when io init not called first +    update_xport_channel_mapping(); +} + +void usrp2_impl::update_xport_channel_mapping(void){ +    if (_io_impl.get() == NULL) return; //not inited yet + +    _io_impl->recv_map.clear(); +    _io_impl->send_map.clear(); + +    for (size_t i = 0; i < _mboards.size(); i++){ + +        subdev_spec_t rx_subdev_spec = _mboards[i]->get_link()[MBOARD_PROP_RX_SUBDEV_SPEC].as<subdev_spec_t>(); +        for (size_t j = 0; j < rx_subdev_spec.size(); j++){ +            _io_impl->recv_map.push_back(i*usrp2_mboard_impl::MAX_NUM_DSPS+j); +            //std::cout << "recv_map.back() " << _io_impl->recv_map.back() << std::endl; +        } + +        subdev_spec_t tx_subdev_spec = _mboards[i]->get_link()[MBOARD_PROP_TX_SUBDEV_SPEC].as<subdev_spec_t>(); +        for (size_t j = 0; j < tx_subdev_spec.size(); j++){ +            _io_impl->send_map.push_back(i*usrp2_mboard_impl::MAX_NUM_DSPS+j); +            //std::cout << "send_map.back() " << _io_impl->send_map.back() << std::endl; +        } + +    } + +    _io_impl->packet_handler_recv_state = vrt_packet_handler::recv_state(_io_impl->recv_map.size()); +    _io_impl->packet_handler_send_state = vrt_packet_handler::send_state(_io_impl->send_map.size());  }  /*********************************************************************** @@ -318,7 +349,7 @@ size_t usrp2_impl::get_max_send_samps_per_packet(void) const{          + vrt_send_header_offset_words32*sizeof(boost::uint32_t)          - sizeof(vrt::if_packet_info_t().cid) //no class id ever used      ; -    const size_t bpp = _data_transports.front()->get_send_frame_size() - hdr_size; +    const size_t bpp = dsp_xports.front()->get_send_frame_size() - hdr_size;      return bpp/_tx_otw_type.get_sample_size();  } @@ -388,49 +419,50 @@ UHD_INLINE bool usrp2_impl::io_impl::get_recv_buffs(      vrt_packet_handler::managed_recv_buffs_t &buffs  ){      if (buffs.size() == 1){ -        buffs[0] = xports[0]->get_recv_buff(recv_timeout); +        buffs[0] = dsp_xports[recv_map[0]]->get_recv_buff(recv_timeout);          if (buffs[0].get() == NULL) return false;          bool clear, msg; time_spec_t time; //unused variables          //call extract_packet_info to handle printing the overflows -        extract_packet_info(buffs[0], this->prev_infos[0], time, clear, msg); +        extract_packet_info(buffs[0], this->prev_infos[recv_map[0]], time, clear, msg);          return true;      }      //-------------------- begin alignment logic ---------------------// +    UHD_ASSERT_THROW(recv_map.size() == buffs.size());      boost::system_time exit_time = boost::get_system_time() + to_time_dur(recv_timeout);      managed_recv_buffer::sptr buff_tmp;      bool clear, msg; -    time_spec_t expected_time; +    size_t index;      //If we did not enter this routine with an empty indexes set,      //jump to after the clear so we can preserve the previous state.      //This saves buffers from being lost when using non-blocking recv. -    if (not indexes_to_do.empty()) goto skip_reset; +    if (not indexes_to_do.empty()) goto skip_pop_initial;      //respond to a clear by starting from scratch      got_clear:      indexes_to_do.reset(buffs.size()); -    skip_reset:      clear = false;      //do an initial pop to load an initial sequence id -    size_t index = indexes_to_do.front(); -    buff_tmp = xports[index]->get_recv_buff(from_time_dur(exit_time - boost::get_system_time())); +    index = indexes_to_do.front(); +    buff_tmp = dsp_xports[recv_map[index]]->get_recv_buff(from_time_dur(exit_time - boost::get_system_time()));      if (buff_tmp.get() == NULL) return false; -    extract_packet_info(buff_tmp, this->prev_infos[index], expected_time, clear, msg); +    extract_packet_info(buff_tmp, this->prev_infos[recv_map[index]], expected_time, clear, msg);      if (clear) goto got_clear;      buffs[index] = buff_tmp;      if (msg) return handle_msg_packet(buffs, index);      indexes_to_do.remove(index); +    skip_pop_initial:      //get an aligned set of elements from the buffers:      while(not indexes_to_do.empty()){          //pop an element off for this index          index = indexes_to_do.front(); -        buff_tmp = xports[index]->get_recv_buff(from_time_dur(exit_time - boost::get_system_time())); +        buff_tmp = dsp_xports[recv_map[index]]->get_recv_buff(from_time_dur(exit_time - boost::get_system_time()));          if (buff_tmp.get() == NULL) return false;          time_spec_t this_time; -        extract_packet_info(buff_tmp, this->prev_infos[index], this_time, clear, msg); +        extract_packet_info(buff_tmp, this->prev_infos[recv_map[index]], this_time, clear, msg);          if (clear) goto got_clear;          buffs[index] = buff_tmp;          if (msg) return handle_msg_packet(buffs, index); @@ -468,13 +500,14 @@ size_t usrp2_impl::get_max_recv_samps_per_packet(void) const{          + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer          - sizeof(vrt::if_packet_info_t().cid) //no class id ever used      ; -    const size_t bpp = _data_transports.front()->get_recv_frame_size() - hdr_size; +    const size_t bpp = dsp_xports.front()->get_recv_frame_size() - hdr_size;      return bpp/_rx_otw_type.get_sample_size();  } -static void handle_overflow(std::vector<usrp2_mboard_impl::sptr> &mboards, size_t chan){ +void usrp2_impl::handle_overflow(size_t chan){      std::cerr << "O" << std::flush; -    mboards.at(chan/mboards.size())->handle_overflow(); +    ldiv_t indexes = ldiv(chan, usrp2_mboard_impl::NUM_RX_DSPS); +    _mboards.at(indexes.quot)->handle_overflow(indexes.rem);  }  size_t usrp2_impl::recv( @@ -491,6 +524,6 @@ size_t usrp2_impl::recv(          _mboards.front()->get_master_clock_freq(), //master clock tick rate          uhd::transport::vrt::if_hdr_unpack_be,          _io_impl->get_recv_buffs_fcn, -        boost::bind(&handle_overflow, boost::ref(_mboards), _1) +        boost::bind(&usrp2_impl::handle_overflow, this, _1)      );  } diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 92a7b2f93..40fc5098b 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -19,11 +19,11 @@  #include "usrp2_regs.hpp"  #include "fw_common.h"  #include <uhd/utils/safe_call.hpp> +#include <uhd/exception.hpp>  #include <uhd/usrp/gps_ctrl.hpp>  #include <uhd/usrp/misc_utils.hpp>  #include <uhd/usrp/dsp_utils.hpp>  #include <uhd/usrp/mboard_props.hpp> -#include <uhd/utils/assert.hpp>  #include <uhd/utils/byteswap.hpp>  #include <uhd/utils/algorithm.hpp>  #include <boost/bind.hpp> @@ -35,35 +35,55 @@ static const size_t mimo_clock_sync_delay_cycles = 137;  using namespace uhd;  using namespace uhd::usrp; +using namespace uhd::transport;  /*********************************************************************** - * Structors + * Helpers   **********************************************************************/ -usrp2_mboard_impl::usrp2_mboard_impl( -    size_t index, -    transport::udp_simple::sptr ctrl_transport, -    transport::zero_copy_if::sptr data_transport, -    transport::zero_copy_if::sptr err0_transport, -    const device_addr_t &device_args, -    size_t recv_samps_per_packet -): -    _index(index), -    _iface(usrp2_iface::make(ctrl_transport)) -{ +static void init_xport(zero_copy_if::sptr xport){      //Send a small data packet so the usrp2 knows the udp source port.      //This setup must happen before further initialization occurs      //or the async update packets will cause ICMP destination unreachable. -    transport::managed_send_buffer::sptr send_buff;      static const boost::uint32_t data[2] = {          uhd::htonx(boost::uint32_t(0 /* don't care seq num */)),          uhd::htonx(boost::uint32_t(USRP2_INVALID_VRT_HEADER))      }; -    send_buff = data_transport->get_send_buff(); -    std::memcpy(send_buff->cast<void*>(), &data, sizeof(data)); -    send_buff->commit(sizeof(data)); -    send_buff = err0_transport->get_send_buff(); + +    transport::managed_send_buffer::sptr send_buff = xport->get_send_buff();      std::memcpy(send_buff->cast<void*>(), &data, sizeof(data));      send_buff->commit(sizeof(data)); +} + +/*********************************************************************** + * Structors + **********************************************************************/ +usrp2_mboard_impl::usrp2_mboard_impl( +    const device_addr_t &device_addr, +    size_t index, usrp2_impl &device +): +    _index(index), _device(device), +    _iface(usrp2_iface::make(udp_simple::make_connected( +        device_addr["addr"], BOOST_STRINGIZE(USRP2_UDP_CTRL_PORT) +    ))) +{ +    //construct transports for dsp and async errors +    std::cout << "Making transport for DSP0..." << std::endl; +    device.dsp_xports.push_back(udp_zero_copy::make( +        device_addr["addr"], BOOST_STRINGIZE(USRP2_UDP_DSP0_PORT), device_addr +    )); +    init_xport(device.dsp_xports.back()); + +    std::cout << "Making transport for DSP1..." << std::endl; +    device.dsp_xports.push_back(udp_zero_copy::make( +        device_addr["addr"], BOOST_STRINGIZE(USRP2_UDP_DSP1_PORT), device_addr +    )); +    init_xport(device.dsp_xports.back()); + +    std::cout << "Making transport for ERR0..." << std::endl; +    device.err_xports.push_back(udp_zero_copy::make( +        device_addr["addr"], BOOST_STRINGIZE(USRP2_UDP_ERR0_PORT), device_addr_t() +    )); +    init_xport(device.err_xports.back());      //contruct the interfaces to mboard perifs      _clock_ctrl = usrp2_clock_ctrl::make(_iface); @@ -74,69 +94,33 @@ usrp2_mboard_impl::usrp2_mboard_impl(      //if(_gps_ctrl->gps_detected()) std::cout << "GPS time: " << _gps_ctrl->get_time() << std::endl; -    //TODO move to dsp impl... -    //load the allowed decim/interp rates -    //_USRP2_RATES = range(4, 128+1, 1) + range(130, 256+1, 2) + range(260, 512+1, 4) -    _allowed_decim_and_interp_rates.clear(); -    for (size_t i = 4; i <= 128; i+=1){ -        _allowed_decim_and_interp_rates.push_back(i); -    } -    for (size_t i = 130; i <= 256; i+=2){ -        _allowed_decim_and_interp_rates.push_back(i); -    } -    for (size_t i = 260; i <= 512; i+=4){ -        _allowed_decim_and_interp_rates.push_back(i); -    } - -    //setup the vrt rx registers -    _iface->poke32(_iface->regs.rx_ctrl_clear_overrun, 1); //reset -    _iface->poke32(_iface->regs.rx_ctrl_nsamps_per_pkt, recv_samps_per_packet); -    _iface->poke32(_iface->regs.rx_ctrl_nchannels, 1); -    _iface->poke32(_iface->regs.rx_ctrl_vrt_header, 0 -        | (0x1 << 28) //if data with stream id -        | (0x1 << 26) //has trailer -        | (0x3 << 22) //integer time other -        | (0x1 << 20) //fractional time sample count -    ); -    _iface->poke32(_iface->regs.rx_ctrl_vrt_stream_id, usrp2_impl::RECV_SID); -    _iface->poke32(_iface->regs.rx_ctrl_vrt_trailer, 0); -    _iface->poke32(_iface->regs.time64_tps, size_t(get_master_clock_freq())); - -    //init the tx control registers -    _iface->poke32(_iface->regs.tx_ctrl_clear_state, 1); //reset -    _iface->poke32(_iface->regs.tx_ctrl_num_chan, 0);    //1 channel -    _iface->poke32(_iface->regs.tx_ctrl_report_sid, usrp2_impl::ASYNC_SID); -    _iface->poke32(_iface->regs.tx_ctrl_policy, U2_FLAG_TX_CTRL_POLICY_NEXT_PACKET); +    //init the dsp stuff (before setting update packets) +    dsp_init();      //setting the cycles per update (disabled by default) -    const double ups_per_sec = device_args.cast<double>("ups_per_sec", 0.0); +    const double ups_per_sec = device_addr.cast<double>("ups_per_sec", 0.0);      if (ups_per_sec > 0.0){          const size_t cycles_per_up = size_t(_clock_ctrl->get_master_clock_rate()/ups_per_sec);          _iface->poke32(_iface->regs.tx_ctrl_cycles_per_up, U2_FLAG_TX_CTRL_UP_ENB | cycles_per_up);      }      //setting the packets per update (enabled by default) -    const double ups_per_fifo = device_args.cast<double>("ups_per_fifo", 8.0); +    size_t send_frame_size = device.dsp_xports[0]->get_send_frame_size(); +    const double ups_per_fifo = device_addr.cast<double>("ups_per_fifo", 8.0);      if (ups_per_fifo > 0.0){ -        const size_t packets_per_up = size_t(usrp2_impl::sram_bytes/ups_per_fifo/data_transport->get_send_frame_size()); +        const size_t packets_per_up = size_t(usrp2_impl::sram_bytes/ups_per_fifo/send_frame_size);          _iface->poke32(_iface->regs.tx_ctrl_packets_per_up, U2_FLAG_TX_CTRL_UP_ENB | packets_per_up);      } -    //init the ddc -    init_ddc_config(); - -    //init the duc -    init_duc_config(); -      //initialize the clock configuration -    if (device_args.has_key("mimo_mode")){ -        if (device_args["mimo_mode"] == "master"){ +    if (device_addr.has_key("mimo_mode")){ +        if (device_addr["mimo_mode"] == "master"){              _mimo_clocking_mode_is_master = true;          } -        else if (device_args["mimo_mode"] == "slave"){ +        else if (device_addr["mimo_mode"] == "slave"){              _mimo_clocking_mode_is_master = false;          } -        else throw std::runtime_error( +        else throw uhd::value_error(              "mimo_mode must be set to master or slave"          );      } @@ -160,13 +144,18 @@ usrp2_mboard_impl::usrp2_mboard_impl(      (*this)[MBOARD_PROP_RX_SUBDEV_SPEC] = subdev_spec_t();      (*this)[MBOARD_PROP_TX_SUBDEV_SPEC] = subdev_spec_t(); +    //------------------------------------------------------------------      //This is a hack/fix for the lingering packet problem.      stream_cmd_t stream_cmd(stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); -    stream_cmd.num_samps = 1; -    this->issue_ddc_stream_cmd(stream_cmd); -    data_transport->get_recv_buff().get(); //recv with timeout for lingering -    data_transport->get_recv_buff().get(); //recv with timeout for expected -    _iface->poke32(_iface->regs.rx_ctrl_clear_overrun, 1); //resets sequence +    for (size_t i = 0; i < NUM_RX_DSPS; i++){ +        size_t index = device.dsp_xports.size() - NUM_RX_DSPS + i; +        stream_cmd.num_samps = 1; +        this->issue_ddc_stream_cmd(stream_cmd, i); +        device.dsp_xports.at(index)->get_recv_buff(0.01).get(); //recv with timeout for lingering +        device.dsp_xports.at(index)->get_recv_buff(0.01).get(); //recv with timeout for expected +        _iface->poke32(_iface->regs.rx_ctrl[i].clear_overrun, 1); //resets sequence +    } +    //------------------------------------------------------------------  }  usrp2_mboard_impl::~usrp2_mboard_impl(void){ @@ -191,14 +180,14 @@ void usrp2_mboard_impl::update_clock_config(void){      //translate pps source enums      switch(_clock_config.pps_source){      case clock_config_t::PPS_SMA:  pps_flags |= U2_FLAG_TIME64_PPS_SMA;  break; -    default: throw std::runtime_error("unhandled clock configuration pps source"); +    default: throw uhd::value_error("unhandled clock configuration pps source");      }      //translate pps polarity enums      switch(_clock_config.pps_polarity){      case clock_config_t::PPS_POS: pps_flags |= U2_FLAG_TIME64_PPS_POSEDGE; break;      case clock_config_t::PPS_NEG: pps_flags |= U2_FLAG_TIME64_PPS_NEGEDGE; break; -    default: throw std::runtime_error("unhandled clock configuration pps polarity"); +    default: throw uhd::value_error("unhandled clock configuration pps polarity");      }      //set the pps flags @@ -211,7 +200,7 @@ void usrp2_mboard_impl::update_clock_config(void){          switch(_clock_config.ref_source){          case clock_config_t::REF_INT : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x12); break;          case clock_config_t::REF_SMA : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x1C); break; -        default: throw std::runtime_error("unhandled clock configuration reference source"); +        default: throw uhd::value_error("unhandled clock configuration reference source");          }          _clock_ctrl->enable_external_ref(true); //USRP2P has an internal 10MHz TCXO          break; @@ -221,7 +210,7 @@ void usrp2_mboard_impl::update_clock_config(void){          switch(_clock_config.ref_source){          case clock_config_t::REF_INT : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x10); break;          case clock_config_t::REF_SMA : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x1C); break; -        default: throw std::runtime_error("unhandled clock configuration reference source"); +        default: throw uhd::value_error("unhandled clock configuration reference source");          }          _clock_ctrl->enable_external_ref(_clock_config.ref_source != clock_config_t::REF_INT);          break; @@ -275,19 +264,6 @@ void usrp2_mboard_impl::set_time_spec(const time_spec_t &time_spec, bool now){      _iface->poke32(_iface->regs.time64_secs, boost::uint32_t(time_spec.get_full_secs()));  } -void usrp2_mboard_impl::handle_overflow(void){ -    if (_continuous_streaming){ //re-issue the stream command if already continuous -        this->issue_ddc_stream_cmd(stream_cmd_t::STREAM_MODE_START_CONTINUOUS); -    } -} - -void usrp2_mboard_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){ -    _continuous_streaming = stream_cmd.stream_mode == stream_cmd_t::STREAM_MODE_START_CONTINUOUS; -    _iface->poke32(_iface->regs.rx_ctrl_stream_cmd, dsp_type1::calc_stream_cmd_word(stream_cmd)); -    _iface->poke32(_iface->regs.rx_ctrl_time_secs,  boost::uint32_t(stream_cmd.time_spec.get_full_secs())); -    _iface->poke32(_iface->regs.rx_ctrl_time_ticks, stream_cmd.time_spec.get_tick_count(get_master_clock_freq())); -} -  /***********************************************************************   * MBoard Get Properties   **********************************************************************/ @@ -324,21 +300,19 @@ void usrp2_mboard_impl::get(const wax::obj &key_, wax::obj &val){          return;      case MBOARD_PROP_RX_DSP: -        UHD_ASSERT_THROW(key.name == ""); -        val = _rx_dsp_proxy->get_link(); +        val = _rx_dsp_proxies[key.name]->get_link();          return;      case MBOARD_PROP_RX_DSP_NAMES: -        val = prop_names_t(1, ""); +        val = _rx_dsp_proxies.keys();          return;      case MBOARD_PROP_TX_DSP: -        UHD_ASSERT_THROW(key.name == ""); -        val = _tx_dsp_proxy->get_link(); +        val = _tx_dsp_proxies[key.name]->get_link();          return;      case MBOARD_PROP_TX_DSP_NAMES: -        val = prop_names_t(1, ""); +        val = _tx_dsp_proxies.keys();          return;      case MBOARD_PROP_CLOCK_CONFIG: @@ -401,30 +375,32 @@ void usrp2_mboard_impl::set(const wax::obj &key, const wax::obj &val){          set_time_spec(val.as<time_spec_t>(), false);          return; -    case MBOARD_PROP_STREAM_CMD: -        issue_ddc_stream_cmd(val.as<stream_cmd_t>()); -        return; -      case MBOARD_PROP_RX_SUBDEV_SPEC:          _rx_subdev_spec = val.as<subdev_spec_t>();          verify_rx_subdev_spec(_rx_subdev_spec, this->get_link());          //sanity check -        UHD_ASSERT_THROW(_rx_subdev_spec.size() == 1); +        UHD_ASSERT_THROW(_rx_subdev_spec.size() <= NUM_RX_DSPS);          //set the mux -        _iface->poke32(_iface->regs.dsp_rx_mux, dsp_type1::calc_rx_mux_word( -            _dboard_manager->get_rx_subdev(_rx_subdev_spec.front().sd_name)[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>() -        )); +        for (size_t i = 0; i < _rx_subdev_spec.size(); i++){ +            if (_rx_subdev_spec.size() >= 1) _iface->poke32(_iface->regs.dsp_rx[i].mux, dsp_type1::calc_rx_mux_word( +                _dboard_manager->get_rx_subdev(_rx_subdev_spec[i].sd_name)[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>() +            )); +        } +        _device.update_xport_channel_mapping();          return;      case MBOARD_PROP_TX_SUBDEV_SPEC:          _tx_subdev_spec = val.as<subdev_spec_t>();          verify_tx_subdev_spec(_tx_subdev_spec, this->get_link());          //sanity check -        UHD_ASSERT_THROW(_tx_subdev_spec.size() == 1); +        UHD_ASSERT_THROW(_tx_subdev_spec.size() <= NUM_TX_DSPS);          //set the mux -        _iface->poke32(_iface->regs.dsp_tx_mux, dsp_type1::calc_tx_mux_word( -            _dboard_manager->get_tx_subdev(_tx_subdev_spec.front().sd_name)[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>() -        )); +        for (size_t i = 0; i < _rx_subdev_spec.size(); i++){ +            _iface->poke32(_iface->regs.dsp_tx_mux, dsp_type1::calc_tx_mux_word( +                _dboard_manager->get_tx_subdev(_tx_subdev_spec[i].sd_name)[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>() +            )); +        } +        _device.update_xport_channel_mapping();          return;      case MBOARD_PROP_EEPROM_MAP: diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp index bd1f5ccb5..e3827233b 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.cpp +++ b/host/lib/usrp/usrp2/usrp2_iface.cpp @@ -18,8 +18,7 @@  #include "usrp2_regs.hpp"  #include "fw_common.h"  #include "usrp2_iface.hpp" -#include <uhd/utils/exception.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp>  #include <uhd/types/dict.hpp>  #include <boost/thread.hpp>  #include <boost/foreach.hpp> @@ -27,7 +26,6 @@  #include <boost/assign/list_of.hpp>  #include <boost/format.hpp>  #include <boost/tokenizer.hpp> -#include <stdexcept>  #include <algorithm>  using namespace uhd; @@ -65,17 +63,13 @@ public:          //check the fpga compatibility number          const boost::uint32_t fpga_compat_num = this->peek32(this->regs.compat_num_rb);          if (fpga_compat_num != USRP2_FPGA_COMPAT_NUM){ -            throw std::runtime_error(str(boost::format( +            throw uhd::runtime_error(str(boost::format(                  "Expected fpga compatibility number %d, but got %d:\n"                  "The fpga build is not compatible with the host code build."              ) % int(USRP2_FPGA_COMPAT_NUM) % fpga_compat_num));          }      } -    ~usrp2_iface_impl(void){ -        /* NOP */ -    } -  /***********************************************************************   * Peek and Poke   **********************************************************************/ @@ -247,7 +241,7 @@ public:          while(true){              size_t len = _ctrl_transport->recv(boost::asio::buffer(usrp2_ctrl_data_in_mem), CTRL_RECV_TIMEOUT);              if(len >= sizeof(boost::uint32_t) and ntohl(ctrl_data_in->proto_ver) != USRP2_FW_COMPAT_NUM){ -                throw std::runtime_error(str(boost::format( +                throw uhd::runtime_error(str(boost::format(                      "Expected protocol compatibility number %d, but got %d:\n"                      "The firmware build is not compatible with the host code build."                  ) % int(USRP2_FW_COMPAT_NUM) % ntohl(ctrl_data_in->proto_ver))); @@ -258,7 +252,7 @@ public:              if (len == 0) break; //timeout              //didnt get seq or bad packet, continue looking...          } -        throw std::runtime_error("no control response"); +        throw uhd::runtime_error("no control response");      }      rev_type get_rev(void){ diff --git a/host/lib/usrp/usrp2/usrp2_iface.hpp b/host/lib/usrp/usrp2/usrp2_iface.hpp index ea42d019f..df53ec66a 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.hpp +++ b/host/lib/usrp/usrp2/usrp2_iface.hpp @@ -19,8 +19,7 @@  #define INCLUDED_USRP2_IFACE_HPP  #include <uhd/transport/udp_simple.hpp> -#include <uhd/types/serial.hpp> -#include <uhd/usrp/mboard_eeprom.hpp> +#include <uhd/usrp/mboard_iface.hpp>  #include <boost/shared_ptr.hpp>  #include <boost/utility.hpp>  #include <boost/cstdint.hpp> @@ -39,10 +38,9 @@ typedef boost::function<std::string(void)> gps_recv_fn_t;   * Provides a set of functions to implementation layer.   * Including spi, peek, poke, control...   */ -class usrp2_iface : public uhd::i2c_iface, boost::noncopyable{ +class usrp2_iface : public uhd::usrp::mboard_iface, boost::noncopyable{  public:      typedef boost::shared_ptr<usrp2_iface> sptr; -      /*!       * Make a new usrp2 interface with the control transport.       * \param ctrl_transport the udp transport object @@ -50,55 +48,6 @@ public:       */      static sptr make(uhd::transport::udp_simple::sptr ctrl_transport); -    /*! -     * Write a register (32 bits) -     * \param addr the address -     * \param data the 32bit data -     */ -    virtual void poke32(boost::uint32_t addr, boost::uint32_t data) = 0; - -    /*! -     * Read a register (32 bits) -     * \param addr the address -     * \return the 32bit data -     */ -    virtual boost::uint32_t peek32(boost::uint32_t addr) = 0; - -    /*! -     * Write a register (16 bits) -     * \param addr the address -     * \param data the 16bit data -     */ -    virtual void poke16(boost::uint32_t addr, boost::uint16_t data) = 0; - -    /*! -     * Read a register (16 bits) -     * \param addr the address -     * \return the 16bit data -     */ -    virtual boost::uint16_t peek16(boost::uint32_t addr) = 0; - -    /*! -     * Perform an spi transaction. -     * \param which_slave the slave device number -     * \param config spi config args -     * \param data the bits to write -     * \param num_bits how many bits in data -     * \param readback true to readback a value -     * \return spi data if readback set -     */ -    virtual boost::uint32_t transact_spi( -        int which_slave, -        const uhd::spi_config_t &config, -        boost::uint32_t data, -        size_t num_bits, -        bool readback -    ) = 0; - -    virtual void write_uart(boost::uint8_t dev, const std::string &buf) = 0; - -    virtual std::string read_uart(boost::uint8_t dev) = 0; -          virtual gps_recv_fn_t get_gps_read_fn(void) = 0;      virtual gps_send_fn_t get_gps_write_fn(void) = 0; diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 8fd88e01d..96552929a 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -17,20 +17,21 @@  #include "usrp2_impl.hpp"  #include "fw_common.h" +#include <uhd/exception.hpp>  #include <uhd/transport/if_addrs.hpp>  #include <uhd/transport/udp_zero_copy.hpp>  #include <uhd/usrp/device_props.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp>  #include <uhd/utils/static.hpp>  #include <uhd/utils/warning.hpp> -#include <boost/algorithm/string.hpp> //for split +#include <uhd/utils/byteswap.hpp>  #include <boost/assign/list_of.hpp>  #include <boost/format.hpp>  #include <boost/foreach.hpp>  #include <boost/lexical_cast.hpp> -#include <boost/regex.hpp>  #include <boost/bind.hpp> -#include <boost/asio.hpp> //htonl and ntohl +#include <boost/asio/ip/address_v4.hpp> +#include <boost/asio.hpp> //used for htonl and ntohl  #include <iostream>  #include <vector> @@ -40,76 +41,21 @@ using namespace uhd::transport;  namespace asio = boost::asio;  /*********************************************************************** - * Helper Functions - **********************************************************************/ -template <class T> std::string num2str(T num){ -    return boost::lexical_cast<std::string>(num); -} - -//! separate indexed device addresses into a vector of device addresses -device_addrs_t sep_indexed_dev_addrs(const device_addr_t &dev_addr){ -    //------------ support old deprecated way and print warning -------- -    if (dev_addr.has_key("addr") and not dev_addr["addr"].empty()){ -        std::vector<std::string> addrs; boost::split(addrs, dev_addr["addr"], boost::is_any_of(" ")); -        if (addrs.size() > 1){ -            device_addr_t fixed_dev_addr = dev_addr; -            fixed_dev_addr.pop("addr"); -            for (size_t i = 0; i < addrs.size(); i++){ -                fixed_dev_addr[str(boost::format("addr%d") % i)] = addrs[i]; -            } -            uhd::warning::post( -                "addr = <space separated list of ip addresses> is deprecated.\n" -                "To address a multi-device, use multiple <key><index> = <val>.\n" -                "See the USRP-NXXX application notes. Two device example:\n" -                "    addr0 = 192.168.10.2\n" -                "    addr1 = 192.168.10.3\n" -            ); -            return sep_indexed_dev_addrs(fixed_dev_addr); -        } -    } -    //------------------------------------------------------------------ -    device_addrs_t dev_addrs; -    BOOST_FOREACH(const std::string &key, dev_addr.keys()){ -        boost::cmatch matches; -        if (not boost::regex_match(key.c_str(), matches, boost::regex("^(\\D+)(\\d*)$"))){ -            throw std::runtime_error("unknown key format: " + key); -        } -        std::string key_part(matches[1].first, matches[1].second); -        std::string num_part(matches[2].first, matches[2].second); -        size_t num = (num_part.empty())? 0 : boost::lexical_cast<size_t>(num_part); -        dev_addrs.resize(std::max(num+1, dev_addrs.size())); -        dev_addrs[num][key_part] = dev_addr[key]; -    } -    return dev_addrs; -} - -//! combine a vector in device addresses into an indexed device address -device_addr_t combine_dev_addr_vector(const device_addrs_t &dev_addrs){ -    device_addr_t dev_addr; -    for (size_t i = 0; i < dev_addrs.size(); i++){ -        BOOST_FOREACH(const std::string &key, dev_addrs[i].keys()){ -            dev_addr[str(boost::format("%s%d") % key % i)] = dev_addrs[i][key]; -        } -    } -    return dev_addr; -} - -/***********************************************************************   * Discovery over the udp transport   **********************************************************************/  static device_addrs_t usrp2_find(const device_addr_t &hint_){      //handle the multi-device discovery -    device_addrs_t hints = sep_indexed_dev_addrs(hint_); +    device_addrs_t hints = separate_device_addr(hint_);      if (hints.size() > 1){          device_addrs_t found_devices;          BOOST_FOREACH(const device_addr_t &hint_i, hints){              device_addrs_t found_devices_i = usrp2_find(hint_i); -            if (found_devices_i.size() != 1) throw std::runtime_error(str(boost::format( +            if (found_devices_i.size() != 1) throw uhd::value_error(str(boost::format(                  "Could not resolve device hint \"%s\" to a single device."              ) % hint_i.to_string()));              found_devices.push_back(found_devices_i[0]);          } -        return device_addrs_t(1, combine_dev_addr_vector(found_devices)); +        return device_addrs_t(1, combine_device_addrs(found_devices));      }      //initialize the hint for a single device case @@ -148,8 +94,8 @@ static device_addrs_t usrp2_find(const device_addr_t &hint_){      //send a hello control packet      usrp2_ctrl_data_t ctrl_data_out; -    ctrl_data_out.proto_ver = htonl(USRP2_FW_COMPAT_NUM); -    ctrl_data_out.id = htonl(USRP2_CTRL_ID_WAZZUP_BRO); +    ctrl_data_out.proto_ver = uhd::htonx<boost::uint32_t>(USRP2_FW_COMPAT_NUM); +    ctrl_data_out.id = uhd::htonx<boost::uint32_t>(USRP2_CTRL_ID_WAZZUP_BRO);      udp_transport->send(boost::asio::buffer(&ctrl_data_out, sizeof(ctrl_data_out)));      //loop and recieve until the timeout @@ -168,9 +114,9 @@ static device_addrs_t usrp2_find(const device_addr_t &hint_){              //This operation can throw due to compatibility mismatch.              //In this case, the discovered device will be ignored.              try{ -                mboard_eeprom_t mb_eeprom = usrp2_iface::make( -                    udp_simple::make_connected(new_addr["addr"], num2str(USRP2_UDP_CTRL_PORT)) -                )->mb_eeprom; +                mboard_eeprom_t mb_eeprom = usrp2_iface::make(udp_simple::make_connected( +                    new_addr["addr"], boost::lexical_cast<std::string>(USRP2_UDP_CTRL_PORT) +                ))->mb_eeprom;                  new_addr["name"] = mb_eeprom["name"];                  new_addr["serial"] = mb_eeprom["serial"];                  if ( @@ -199,57 +145,111 @@ static device_addrs_t usrp2_find(const device_addr_t &hint_){   * Make   **********************************************************************/  static device::sptr usrp2_make(const device_addr_t &device_addr){ +    return device::sptr(new usrp2_impl(device_addr)); +} -    //setup the dsp transport hints (default to a large recv buff) -    device_addr_t dsp_xport_hints = device_addr; -    if (not dsp_xport_hints.has_key("recv_buff_size")){ -        //only enable on platforms that are happy with the large buffer resize -        #if defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32) -            //set to half-a-second of buffering at max rate -            dsp_xport_hints["recv_buff_size"] = "50e6"; -        #endif /*defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32)*/ -    } +UHD_STATIC_BLOCK(register_usrp2_device){ +    device::register_device(&usrp2_find, &usrp2_make); +} -    //create a ctrl and data transport for each address -    std::vector<udp_simple::sptr> ctrl_transports; -    std::vector<zero_copy_if::sptr> data_transports; -    std::vector<zero_copy_if::sptr> err0_transports; -    const device_addrs_t device_addrs = sep_indexed_dev_addrs(device_addr); +/*********************************************************************** + * MTU Discovery + **********************************************************************/ +struct mtu_result_t{ +    size_t recv_mtu, send_mtu; +}; + +static mtu_result_t determine_mtu(const std::string &addr){ +    udp_simple::sptr udp_sock = udp_simple::make_connected( +        addr, BOOST_STRINGIZE(USRP2_UDP_CTRL_PORT) +    ); + +    //The FPGA offers 4K buffers, and the user may manually request this. +    //However, multiple simultaneous receives (2DSP slave + 2DSP master), +    //require that buffering to be used internally, and this is a safe setting. +    boost::uint8_t buffer[2000]; +    usrp2_ctrl_data_t *ctrl_data = reinterpret_cast<usrp2_ctrl_data_t *>(buffer); +    static const double echo_timeout = 0.020; //20 ms + +    size_t min_recv_mtu = sizeof(usrp2_ctrl_data_t), max_recv_mtu = sizeof(buffer); +    size_t min_send_mtu = sizeof(usrp2_ctrl_data_t), max_send_mtu = sizeof(buffer); + +    while (min_recv_mtu < max_recv_mtu){ + +        size_t test_mtu = (max_recv_mtu/2 + min_recv_mtu/2 + 3) & ~3; +        //std::cout << "recv_mtu " << mtu.recv_mtu << std::endl; + +        ctrl_data->id = htonl(USRP2_CTRL_ID_HOLLER_AT_ME_BRO); +        ctrl_data->proto_ver = htonl(USRP2_FW_COMPAT_NUM); +        ctrl_data->data.echo_args.len = htonl(test_mtu); +        udp_sock->send(boost::asio::buffer(buffer, sizeof(usrp2_ctrl_data_t))); + +        size_t len = udp_sock->recv(boost::asio::buffer(buffer), echo_timeout); + +        if (len >= test_mtu) min_recv_mtu = test_mtu; +        else                 max_recv_mtu = test_mtu - 4; -    BOOST_FOREACH(const device_addr_t &dev_addr_i, device_addrs){ -        ctrl_transports.push_back(udp_simple::make_connected( -            dev_addr_i["addr"], num2str(USRP2_UDP_CTRL_PORT) -        )); -        data_transports.push_back(udp_zero_copy::make( -            dev_addr_i["addr"], num2str(USRP2_UDP_DATA_PORT), dsp_xport_hints -        )); -        err0_transports.push_back(udp_zero_copy::make( -            dev_addr_i["addr"], num2str(USRP2_UDP_ERR0_PORT), device_addr_t() -        ));      } -    //create the usrp2 implementation guts -    return device::sptr(new usrp2_impl( -        ctrl_transports, data_transports, err0_transports, device_addrs -    )); -} +    while (min_send_mtu < max_send_mtu){ -UHD_STATIC_BLOCK(register_usrp2_device){ -    device::register_device(&usrp2_find, &usrp2_make); +        size_t test_mtu = (max_send_mtu/2 + min_send_mtu/2 + 3) & ~3; +        //std::cout << "send_mtu " << mtu.send_mtu << std::endl; + +        ctrl_data->id = htonl(USRP2_CTRL_ID_HOLLER_AT_ME_BRO); +        ctrl_data->proto_ver = htonl(USRP2_FW_COMPAT_NUM); +        ctrl_data->data.echo_args.len = htonl(sizeof(usrp2_ctrl_data_t)); +        udp_sock->send(boost::asio::buffer(buffer, test_mtu)); + +        size_t len = udp_sock->recv(boost::asio::buffer(buffer), echo_timeout); +        if (len >= sizeof(usrp2_ctrl_data_t)) len = ntohl(ctrl_data->data.echo_args.len); + +        if (len >= test_mtu) min_send_mtu = test_mtu; +        else                 max_send_mtu = test_mtu - 4; +    } + +    mtu_result_t mtu; +    mtu.recv_mtu = min_recv_mtu; +    mtu.send_mtu = min_send_mtu; +    return mtu;  }  /***********************************************************************   * Structors   **********************************************************************/ -usrp2_impl::usrp2_impl( -    std::vector<udp_simple::sptr> ctrl_transports, -    std::vector<zero_copy_if::sptr> data_transports, -    std::vector<zero_copy_if::sptr> err0_transports, -    const device_addrs_t &device_args -): -    _data_transports(data_transports), -    _err0_transports(err0_transports) -{ +usrp2_impl::usrp2_impl(const device_addr_t &_device_addr){ +    device_addr_t device_addr = _device_addr; + +    //setup the dsp transport hints (default to a large recv buff) +    if (not device_addr.has_key("recv_buff_size")){ +        #if defined(UHD_PLATFORM_MACOS) || defined(UHD_PLATFORM_BSD) +            //limit buffer resize on macos or it will error +            device_addr["recv_buff_size"] = "1e6"; +        #elif defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32) +            //set to half-a-second of buffering at max rate +            device_addr["recv_buff_size"] = "50e6"; +        #endif +    } + +    device_addrs_t device_args = separate_device_addr(device_addr); + +    //calculate the minimum send and recv mtu of all devices +    mtu_result_t mtu = determine_mtu(device_args[0]["addr"]); +    for (size_t i = 1; i < device_args.size(); i++){ +        mtu_result_t mtu_i = determine_mtu(device_args[i]["addr"]); +        mtu.recv_mtu = std::min(mtu.recv_mtu, mtu_i.recv_mtu); +        mtu.send_mtu = std::min(mtu.send_mtu, mtu_i.send_mtu); +    } + +    std::cout << "mtu recv bytes " << mtu.recv_mtu << std::endl; +    std::cout << "mtu send bytes " << mtu.send_mtu << std::endl; + +    //use the discovered mtu if not specified by the user +    if (not device_addr.has_key("recv_frame_size")) +        device_addr["recv_frame_size"] = boost::lexical_cast<std::string>(mtu.recv_mtu); +    if (not device_addr.has_key("send_frame_size")) +        device_addr["send_frame_size"] = boost::lexical_cast<std::string>(mtu.send_mtu); +      //setup rx otw type      _rx_otw_type.width = 16;      _rx_otw_type.shift = 0; @@ -264,13 +264,16 @@ usrp2_impl::usrp2_impl(      //create a new mboard handler for each control transport      for(size_t i = 0; i < device_args.size(); i++){ -        _mboards.push_back(usrp2_mboard_impl::sptr(new usrp2_mboard_impl( -            i, ctrl_transports[i], data_transports[i], -            err0_transports[i], device_args[i], -            this->get_max_recv_samps_per_packet() -        ))); +        device_addr_t dev_addr_i = device_args[i]; +        BOOST_FOREACH(const std::string &key, device_addr.keys()){ +            if (dev_addr_i.has_key(key)) continue; +            dev_addr_i[key] = device_addr[key]; +        } +        _mboards.push_back(usrp2_mboard_impl::sptr( +            new usrp2_mboard_impl(dev_addr_i, i, *this) +        ));          //use an empty name when there is only one mboard -        std::string name = (ctrl_transports.size() > 1)? boost::lexical_cast<std::string>(i) : ""; +        std::string name = (device_args.size() > 1)? boost::lexical_cast<std::string>(i) : "";          _mboard_dict[name] = _mboards.back();      } diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 337f842d6..0676cecf2 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -71,6 +71,8 @@ private:      void set(const wax::obj &key, const wax::obj &val){return _set(key, val);}  }; +class usrp2_impl; +  /*!   * USRP2 mboard implementation guts:   * The implementation details are encapsulated here. @@ -80,14 +82,14 @@ class usrp2_mboard_impl : public wax::obj{  public:      typedef boost::shared_ptr<usrp2_mboard_impl> sptr; +    static const size_t NUM_RX_DSPS = 2; +    static const size_t NUM_TX_DSPS = 1; +    static const size_t MAX_NUM_DSPS = 2; +      //structors      usrp2_mboard_impl( -        size_t index, -        uhd::transport::udp_simple::sptr, -        uhd::transport::zero_copy_if::sptr, -        uhd::transport::zero_copy_if::sptr, -        const uhd::device_addr_t &device_args, -        size_t recv_samps_per_packet +        const uhd::device_addr_t &device_addr, +        size_t index, usrp2_impl &device      );      ~usrp2_mboard_impl(void); @@ -95,11 +97,11 @@ public:          return _clock_ctrl->get_master_clock_rate();      } -    void handle_overflow(void); +    void handle_overflow(size_t);  private:      size_t _index; -    bool _continuous_streaming; +    usrp2_impl &_device;      bool _mimo_clocking_mode_is_master;      //interfaces @@ -147,27 +149,20 @@ private:      wax_obj_proxy::sptr _tx_dboard_proxy;      uhd::usrp::dboard_eeprom_t _tx_db_eeprom; -    //methods and shadows for the ddc dsp -    std::vector<size_t> _allowed_decim_and_interp_rates; -    size_t _ddc_decim; -    double _ddc_freq; -    void init_ddc_config(void); -    void issue_ddc_stream_cmd(const uhd::stream_cmd_t &stream_cmd); - -    //methods and shadows for the duc dsp -    size_t _duc_interp; -    double _duc_freq; -    void init_duc_config(void); +    //methods and shadows for the dsps +    UHD_PIMPL_DECL(dsp_impl) _dsp_impl; +    void dsp_init(void); +    void issue_ddc_stream_cmd(const uhd::stream_cmd_t &, size_t);      //properties interface for ddc -    void ddc_get(const wax::obj &, wax::obj &); -    void ddc_set(const wax::obj &, const wax::obj &); -    wax_obj_proxy::sptr _rx_dsp_proxy; +    void ddc_get(const wax::obj &, wax::obj &, size_t); +    void ddc_set(const wax::obj &, const wax::obj &, size_t); +    uhd::dict<std::string, wax_obj_proxy::sptr> _rx_dsp_proxies;      //properties interface for duc -    void duc_get(const wax::obj &, wax::obj &); -    void duc_set(const wax::obj &, const wax::obj &); -    wax_obj_proxy::sptr _tx_dsp_proxy; +    void duc_get(const wax::obj &, wax::obj &, size_t); +    void duc_set(const wax::obj &, const wax::obj &, size_t); +    uhd::dict<std::string, wax_obj_proxy::sptr> _tx_dsp_proxies;  }; @@ -182,19 +177,7 @@ public:      static const boost::uint32_t RECV_SID = 1;      static const boost::uint32_t ASYNC_SID = 2; -    /*! -     * Create a new usrp2 impl base. -     * \param ctrl_transports the udp transports for control -     * \param data_transports the udp transports for data -     * \param err0_transports the udp transports for error -     * \param device_args optional misc device parameters -     */ -    usrp2_impl( -        std::vector<uhd::transport::udp_simple::sptr> ctrl_transports, -        std::vector<uhd::transport::zero_copy_if::sptr> data_transports, -        std::vector<uhd::transport::zero_copy_if::sptr> err0_transports, -        const uhd::device_addrs_t &device_args -    ); +    usrp2_impl(const uhd::device_addr_t &);      ~usrp2_impl(void); @@ -213,6 +196,14 @@ public:      size_t get_max_recv_samps_per_packet(void) const;      bool recv_async_msg(uhd::async_metadata_t &, double); +    void update_xport_channel_mapping(void); + +    //public frame sizes, set by mboard, used by io impl +    size_t recv_frame_size, send_frame_size; + +    std::vector<uhd::transport::zero_copy_if::sptr> dsp_xports; +    std::vector<uhd::transport::zero_copy_if::sptr> err_xports; +  private:      //device properties interface      void get(const wax::obj &, wax::obj &); @@ -223,11 +214,10 @@ private:      uhd::dict<std::string, usrp2_mboard_impl::sptr> _mboard_dict;      //io impl methods and members -    std::vector<uhd::transport::zero_copy_if::sptr> _data_transports; -    std::vector<uhd::transport::zero_copy_if::sptr> _err0_transports;      uhd::otw_type_t _rx_otw_type, _tx_otw_type;      UHD_PIMPL_DECL(io_impl) _io_impl;      void io_init(void); +    void handle_overflow(size_t);  };  #endif /* INCLUDED_USRP2_IMPL_HPP */ diff --git a/host/lib/usrp/usrp2/usrp2_regs.cpp b/host/lib/usrp/usrp2/usrp2_regs.cpp index 84907c32e..66c3ac137 100644 --- a/host/lib/usrp/usrp2/usrp2_regs.cpp +++ b/host/lib/usrp/usrp2/usrp2_regs.cpp @@ -38,8 +38,10 @@ usrp2_regs_t usrp2_get_regs(bool use_n2xx_map) {    x.sr_udp_sm = 96;    x.sr_tx_dsp = 208;    x.sr_tx_ctrl = 224; -  x.sr_rx_dsp = 160; -  x.sr_rx_ctrl = 176; +  x.sr_rx_dsp0 = 160; +  x.sr_rx_ctrl0 = 176; +  x.sr_rx_dsp1 = 240; +  x.sr_rx_ctrl1 = 32;    x.sr_time64 = 192;    x.sr_simtimer = 198;    x.sr_last = 255; @@ -68,12 +70,18 @@ usrp2_regs_t usrp2_get_regs(bool use_n2xx_map) {    x.dsp_tx_scale_iq = sr_addr(misc_output_base, x.sr_tx_dsp + 1);    x.dsp_tx_interp_rate = sr_addr(misc_output_base, x.sr_tx_dsp + 2);    x.dsp_tx_mux = sr_addr(misc_output_base, x.sr_tx_dsp + 4); -  x.dsp_rx_freq = sr_addr(misc_output_base, x.sr_rx_dsp + 0); -  x.dsp_rx_scale_iq = sr_addr(misc_output_base, x.sr_rx_dsp + 1); -  x.dsp_rx_decim_rate = sr_addr(misc_output_base, x.sr_rx_dsp + 2); -  x.dsp_rx_dcoffset_i = sr_addr(misc_output_base, x.sr_rx_dsp + 3); -  x.dsp_rx_dcoffset_q = sr_addr(misc_output_base, x.sr_rx_dsp + 4); -  x.dsp_rx_mux = sr_addr(misc_output_base, x.sr_rx_dsp + 5); +  x.dsp_rx[0].freq = sr_addr(misc_output_base, x.sr_rx_dsp0 + 0); +  x.dsp_rx[0].scale_iq = sr_addr(misc_output_base, x.sr_rx_dsp0 + 1); +  x.dsp_rx[0].decim_rate = sr_addr(misc_output_base, x.sr_rx_dsp0 + 2); +  x.dsp_rx[0].dcoffset_i = sr_addr(misc_output_base, x.sr_rx_dsp0 + 3); +  x.dsp_rx[0].dcoffset_q = sr_addr(misc_output_base, x.sr_rx_dsp0 + 4); +  x.dsp_rx[0].mux = sr_addr(misc_output_base, x.sr_rx_dsp0 + 5); +  x.dsp_rx[1].freq = sr_addr(misc_output_base, x.sr_rx_dsp1 + 0); +  x.dsp_rx[1].scale_iq = sr_addr(misc_output_base, x.sr_rx_dsp1 + 1); +  x.dsp_rx[1].decim_rate = sr_addr(misc_output_base, x.sr_rx_dsp1 + 2); +  x.dsp_rx[1].dcoffset_i = sr_addr(misc_output_base, x.sr_rx_dsp1 + 3); +  x.dsp_rx[1].dcoffset_q = sr_addr(misc_output_base, x.sr_rx_dsp1 + 4); +  x.dsp_rx[1].mux = sr_addr(misc_output_base, x.sr_rx_dsp1 + 5);    x.gpio_io = gpio_base + 0;    x.gpio_ddr = gpio_base + 4;    x.gpio_tx_sel = gpio_base + 8; @@ -86,15 +94,24 @@ usrp2_regs_t usrp2_get_regs(bool use_n2xx_map) {    x.atr_inrx_rxside = atr_base + 10;    x.atr_full_txside = atr_base + 12;    x.atr_full_rxside = atr_base + 14; -  x.rx_ctrl_stream_cmd = sr_addr(misc_output_base, x.sr_rx_ctrl + 0); -  x.rx_ctrl_time_secs = sr_addr(misc_output_base, x.sr_rx_ctrl + 1); -  x.rx_ctrl_time_ticks = sr_addr(misc_output_base, x.sr_rx_ctrl + 2); -  x.rx_ctrl_clear_overrun = sr_addr(misc_output_base, x.sr_rx_ctrl + 3); -  x.rx_ctrl_vrt_header = sr_addr(misc_output_base, x.sr_rx_ctrl + 4); -  x.rx_ctrl_vrt_stream_id = sr_addr(misc_output_base, x.sr_rx_ctrl + 5); -  x.rx_ctrl_vrt_trailer = sr_addr(misc_output_base, x.sr_rx_ctrl + 6); -  x.rx_ctrl_nsamps_per_pkt = sr_addr(misc_output_base, x.sr_rx_ctrl + 7); -  x.rx_ctrl_nchannels = sr_addr(misc_output_base, x.sr_rx_ctrl + 8); +  x.rx_ctrl[0].stream_cmd = sr_addr(misc_output_base, x.sr_rx_ctrl0 + 0); +  x.rx_ctrl[0].time_secs = sr_addr(misc_output_base, x.sr_rx_ctrl0 + 1); +  x.rx_ctrl[0].time_ticks = sr_addr(misc_output_base, x.sr_rx_ctrl0 + 2); +  x.rx_ctrl[0].clear_overrun = sr_addr(misc_output_base, x.sr_rx_ctrl0 + 3); +  x.rx_ctrl[0].vrt_header = sr_addr(misc_output_base, x.sr_rx_ctrl0 + 4); +  x.rx_ctrl[0].vrt_stream_id = sr_addr(misc_output_base, x.sr_rx_ctrl0 + 5); +  x.rx_ctrl[0].vrt_trailer = sr_addr(misc_output_base, x.sr_rx_ctrl0 + 6); +  x.rx_ctrl[0].nsamps_per_pkt = sr_addr(misc_output_base, x.sr_rx_ctrl0 + 7); +  x.rx_ctrl[0].nchannels = sr_addr(misc_output_base, x.sr_rx_ctrl0 + 8); +  x.rx_ctrl[1].stream_cmd = sr_addr(misc_output_base, x.sr_rx_ctrl1 + 0); +  x.rx_ctrl[1].time_secs = sr_addr(misc_output_base, x.sr_rx_ctrl1 + 1); +  x.rx_ctrl[1].time_ticks = sr_addr(misc_output_base, x.sr_rx_ctrl1 + 2); +  x.rx_ctrl[1].clear_overrun = sr_addr(misc_output_base, x.sr_rx_ctrl1 + 3); +  x.rx_ctrl[1].vrt_header = sr_addr(misc_output_base, x.sr_rx_ctrl1 + 4); +  x.rx_ctrl[1].vrt_stream_id = sr_addr(misc_output_base, x.sr_rx_ctrl1 + 5); +  x.rx_ctrl[1].vrt_trailer = sr_addr(misc_output_base, x.sr_rx_ctrl1 + 6); +  x.rx_ctrl[1].nsamps_per_pkt = sr_addr(misc_output_base, x.sr_rx_ctrl1 + 7); +  x.rx_ctrl[1].nchannels = sr_addr(misc_output_base, x.sr_rx_ctrl1 + 8);    x.tx_ctrl_num_chan = sr_addr(misc_output_base, x.sr_tx_ctrl + 0);    x.tx_ctrl_clear_state = sr_addr(misc_output_base, x.sr_tx_ctrl + 1);    x.tx_ctrl_report_sid = sr_addr(misc_output_base, x.sr_tx_ctrl + 2); diff --git a/host/lib/usrp/usrp2/usrp2_regs.hpp b/host/lib/usrp/usrp2/usrp2_regs.hpp index 977b342cb..01f5ee65a 100644 --- a/host/lib/usrp/usrp2/usrp2_regs.hpp +++ b/host/lib/usrp/usrp2/usrp2_regs.hpp @@ -38,8 +38,10 @@ typedef struct {      int sr_udp_sm;      int sr_tx_dsp;      int sr_tx_ctrl; -    int sr_rx_dsp; -    int sr_rx_ctrl; +    int sr_rx_dsp0; +    int sr_rx_ctrl0; +    int sr_rx_dsp1; +    int sr_rx_ctrl1;      int sr_time64;      int sr_simtimer;      int sr_last; @@ -68,12 +70,14 @@ typedef struct {      int dsp_tx_scale_iq;      int dsp_tx_interp_rate;      int dsp_tx_mux; -    int dsp_rx_freq; -    int dsp_rx_scale_iq; -    int dsp_rx_decim_rate; -    int dsp_rx_dcoffset_i; -    int dsp_rx_dcoffset_q; -    int dsp_rx_mux; +    struct{ +        int freq; +        int scale_iq; +        int decim_rate; +        int dcoffset_i; +        int dcoffset_q; +        int mux; +    } dsp_rx[2];      int gpio_base;      int gpio_io;      int gpio_ddr; @@ -88,15 +92,17 @@ typedef struct {      int atr_inrx_rxside;      int atr_full_txside;      int atr_full_rxside; -    int rx_ctrl_stream_cmd; -    int rx_ctrl_time_secs; -    int rx_ctrl_time_ticks; -    int rx_ctrl_clear_overrun; -    int rx_ctrl_vrt_header; -    int rx_ctrl_vrt_stream_id; -    int rx_ctrl_vrt_trailer; -    int rx_ctrl_nsamps_per_pkt; -    int rx_ctrl_nchannels; +    struct{ +        int stream_cmd; +        int time_secs; +        int time_ticks; +        int clear_overrun; +        int vrt_header; +        int vrt_stream_id; +        int vrt_trailer; +        int nsamps_per_pkt; +        int nchannels; +    } rx_ctrl[2];      int tx_ctrl_num_chan;      int tx_ctrl_clear_state;      int tx_ctrl_report_sid; diff --git a/host/lib/usrp/usrp_e100/clock_ctrl.cpp b/host/lib/usrp/usrp_e100/clock_ctrl.cpp index e29fe18ce..aba630d88 100644 --- a/host/lib/usrp/usrp_e100/clock_ctrl.cpp +++ b/host/lib/usrp/usrp_e100/clock_ctrl.cpp @@ -17,7 +17,7 @@  #include "clock_ctrl.hpp"  #include "ad9522_regs.hpp" -#include <uhd/utils/assert.hpp> +#include <uhd/utils/assert_has.hpp>  #include <boost/cstdint.hpp>  #include "usrp_e100_regs.hpp" //spi slave constants  #include <boost/assign/list_of.hpp> @@ -158,7 +158,7 @@ static clock_settings_type get_clock_settings(double rate){          }      } -    throw std::runtime_error(str(boost::format( +    throw uhd::value_error(str(boost::format(          "USRP-E100 clock control: could not calculate settings for clock rate %fMHz"      ) % (rate/1e6)));  } @@ -302,7 +302,7 @@ public:          _ad9522_regs.out4_cmos_configuration = (enb)?              ad9522_regs_t::OUT4_CMOS_CONFIGURATION_A_ON :              ad9522_regs_t::OUT4_CMOS_CONFIGURATION_OFF; -        this->send_reg(0x0F0); +        this->send_reg(0x0F4);          this->latch_regs();      } @@ -409,10 +409,10 @@ private:      void send_reg(boost::uint16_t addr){          boost::uint32_t reg = _ad9522_regs.get_write_reg(addr);          //std::cout << "clock control write reg: " << std::hex << reg << std::endl; -        _iface->transact_spi( +        _iface->write_spi(              UE_SPI_SS_AD9522,              spi_config_t::EDGE_RISE, -            reg, 24, false /*no rb*/ +            reg, 24          );      } @@ -427,9 +427,9 @@ private:          //wait for calibration done:          static const boost::uint8_t addr = 0x01F;          for (size_t ms10 = 0; ms10 < 100; ms10++){ -            boost::uint32_t reg = _iface->transact_spi( +            boost::uint32_t reg = _iface->read_spi(                  UE_SPI_SS_AD9522, spi_config_t::EDGE_RISE, -                _ad9522_regs.get_read_reg(addr), 24, true /*rb*/ +                _ad9522_regs.get_read_reg(addr), 24              );              _ad9522_regs.set_reg(addr, reg);              if (_ad9522_regs.vco_calibration_finished) return; diff --git a/host/lib/usrp/usrp_e100/codec_ctrl.cpp b/host/lib/usrp/usrp_e100/codec_ctrl.cpp index b33c8ae65..50442546a 100644 --- a/host/lib/usrp/usrp_e100/codec_ctrl.cpp +++ b/host/lib/usrp/usrp_e100/codec_ctrl.cpp @@ -18,7 +18,7 @@  #include "codec_ctrl.hpp"  #include "ad9862_regs.hpp"  #include <uhd/types/dict.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp>  #include <uhd/utils/algorithm.hpp>  #include <boost/cstdint.hpp>  #include <boost/tuple/tuple.hpp> @@ -137,7 +137,7 @@ static const int mtpgw = 255; //maximum tx pga gain word  void usrp_e100_codec_ctrl_impl::set_tx_pga_gain(double gain){      int gain_word = int(mtpgw*(gain - tx_pga_gain_range.start())/(tx_pga_gain_range.stop() - tx_pga_gain_range.start())); -    _ad9862_regs.tx_pga_gain = std::clip(gain_word, 0, mtpgw); +    _ad9862_regs.tx_pga_gain = uhd::clip(gain_word, 0, mtpgw);      this->send_reg(16);  } @@ -149,7 +149,7 @@ static const int mrpgw = 0x14; //maximum rx pga gain word  void usrp_e100_codec_ctrl_impl::set_rx_pga_gain(double gain, char which){      int gain_word = int(mrpgw*(gain - rx_pga_gain_range.start())/(rx_pga_gain_range.stop() - rx_pga_gain_range.start())); -    gain_word = std::clip(gain_word, 0, mrpgw); +    gain_word = uhd::clip(gain_word, 0, mrpgw);      switch(which){      case 'A':          _ad9862_regs.rx_pga_a = gain_word; @@ -227,7 +227,7 @@ double usrp_e100_codec_ctrl_impl::read_aux_adc(aux_adc_t which){      case AUX_ADC_B1: return aux_adc_to_volts(_ad9862_regs.aux_adc_b1_9_2, _ad9862_regs.aux_adc_b1_1_0);      case AUX_ADC_B2: return aux_adc_to_volts(_ad9862_regs.aux_adc_b2_9_2, _ad9862_regs.aux_adc_b2_1_0);      } -    UHD_ASSERT_THROW(false); +    UHD_THROW_INVALID_CODE_PATH();  }  /*********************************************************************** @@ -236,7 +236,7 @@ double usrp_e100_codec_ctrl_impl::read_aux_adc(aux_adc_t which){  void usrp_e100_codec_ctrl_impl::write_aux_dac(aux_dac_t which, double volts){      //special case for aux dac d (aka sigma delta word)      if (which == AUX_DAC_D){ -        boost::uint16_t dac_word = std::clip(boost::math::iround(volts*0xfff/3.3), 0, 0xfff); +        boost::uint16_t dac_word = uhd::clip(boost::math::iround(volts*0xfff/3.3), 0, 0xfff);          _ad9862_regs.sig_delt_11_4 = boost::uint8_t(dac_word >> 4);          _ad9862_regs.sig_delt_3_0 = boost::uint8_t(dac_word & 0xf);          this->send_reg(42); @@ -245,7 +245,7 @@ void usrp_e100_codec_ctrl_impl::write_aux_dac(aux_dac_t which, double volts){      }      //calculate the dac word for aux dac a, b, c -    boost::uint8_t dac_word = std::clip(boost::math::iround(volts*0xff/3.3), 0, 0xff); +    boost::uint8_t dac_word = uhd::clip(boost::math::iround(volts*0xff/3.3), 0, 0xff);      //setup a lookup table for the aux dac params (reg ref, reg addr)      typedef boost::tuple<boost::uint8_t*, boost::uint8_t> dac_params_t; @@ -269,20 +269,20 @@ void usrp_e100_codec_ctrl_impl::write_aux_dac(aux_dac_t which, double volts){  void usrp_e100_codec_ctrl_impl::send_reg(boost::uint8_t addr){      boost::uint32_t reg = _ad9862_regs.get_write_reg(addr);      if (codec_debug) std::cout << "codec control write reg: " << std::hex << reg << std::endl; -    _iface->transact_spi( +    _iface->write_spi(          UE_SPI_SS_AD9862,          spi_config_t::EDGE_RISE, -        reg, 16, false /*no rb*/ +        reg, 16      );  }  void usrp_e100_codec_ctrl_impl::recv_reg(boost::uint8_t addr){      boost::uint32_t reg = _ad9862_regs.get_read_reg(addr);      if (codec_debug) std::cout << "codec control read reg: " << std::hex << reg << std::endl; -    boost::uint32_t ret = _iface->transact_spi( +    boost::uint32_t ret = _iface->read_spi(          UE_SPI_SS_AD9862,          spi_config_t::EDGE_RISE, -        reg, 16, true /*rb*/ +        reg, 16      );      if (codec_debug) std::cout << "codec control read ret: " << std::hex << ret << std::endl;      _ad9862_regs.set_reg(addr, boost::uint16_t(ret)); diff --git a/host/lib/usrp/usrp_e100/codec_impl.cpp b/host/lib/usrp/usrp_e100/codec_impl.cpp index 0d91fb42c..ae198aaa5 100644 --- a/host/lib/usrp/usrp_e100/codec_impl.cpp +++ b/host/lib/usrp/usrp_e100/codec_impl.cpp @@ -16,7 +16,7 @@  //  #include "usrp_e100_impl.hpp" -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp>  #include <uhd/usrp/codec_props.hpp>  #include <boost/bind.hpp> diff --git a/host/lib/usrp/usrp_e100/dboard_iface.cpp b/host/lib/usrp/usrp_e100/dboard_iface.cpp index e4c3856c9..4ee354486 100644 --- a/host/lib/usrp/usrp_e100/dboard_iface.cpp +++ b/host/lib/usrp/usrp_e100/dboard_iface.cpp @@ -21,7 +21,7 @@  #include "codec_ctrl.hpp"  #include <uhd/usrp/dboard_iface.hpp>  #include <uhd/types/dict.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp>  #include <boost/assign/list_of.hpp>  #include <linux/usrp_e.h> //i2c and spi constants @@ -235,7 +235,7 @@ static boost::uint32_t unit_to_otw_spi_dev(dboard_iface::unit_t unit){      case dboard_iface::UNIT_TX: return UE_SPI_SS_TX_DB;      case dboard_iface::UNIT_RX: return UE_SPI_SS_RX_DB;      } -    throw std::invalid_argument("unknown unit type"); +    UHD_THROW_INVALID_CODE_PATH();  }  void usrp_e100_dboard_iface::write_spi( @@ -244,7 +244,7 @@ void usrp_e100_dboard_iface::write_spi(      boost::uint32_t data,      size_t num_bits  ){ -    _iface->transact_spi(unit_to_otw_spi_dev(unit), config, data, num_bits, false /*no rb*/); +    _iface->write_spi(unit_to_otw_spi_dev(unit), config, data, num_bits);  }  boost::uint32_t usrp_e100_dboard_iface::read_write_spi( @@ -253,7 +253,7 @@ boost::uint32_t usrp_e100_dboard_iface::read_write_spi(      boost::uint32_t data,      size_t num_bits  ){ -    return _iface->transact_spi(unit_to_otw_spi_dev(unit), config, data, num_bits, true /*rb*/); +    return _iface->read_spi(unit_to_otw_spi_dev(unit), config, data, num_bits);  }  /*********************************************************************** diff --git a/host/lib/usrp/usrp_e100/dboard_impl.cpp b/host/lib/usrp/usrp_e100/dboard_impl.cpp index b533c2657..0b89fed9f 100644 --- a/host/lib/usrp/usrp_e100/dboard_impl.cpp +++ b/host/lib/usrp/usrp_e100/dboard_impl.cpp @@ -17,7 +17,7 @@  #include "usrp_e100_impl.hpp"  #include "usrp_e100_regs.hpp" -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp>  #include <uhd/usrp/dboard_props.hpp>  #include <uhd/usrp/subdev_props.hpp>  #include <uhd/usrp/misc_utils.hpp> diff --git a/host/lib/usrp/usrp_e100/dsp_impl.cpp b/host/lib/usrp/usrp_e100/dsp_impl.cpp index 7d358a607..8d084f066 100644 --- a/host/lib/usrp/usrp_e100/dsp_impl.cpp +++ b/host/lib/usrp/usrp_e100/dsp_impl.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 @@ -60,10 +60,6 @@ void usrp_e100_impl::rx_ddc_get(const wax::obj &key_, wax::obj &val){          val = _ddc_freq;          return; -    case DSP_PROP_FREQ_SHIFT_NAMES: -        val = prop_names_t(1, ""); -        return; -      case DSP_PROP_CODEC_RATE:          val = _clock_ctrl->get_fpga_clock_rate();          return; @@ -84,6 +80,10 @@ void usrp_e100_impl::rx_ddc_set(const wax::obj &key_, const wax::obj &val){      switch(key.as<dsp_prop_t>()){ +    case DSP_PROP_STREAM_CMD: +        issue_stream_cmd(val.as<stream_cmd_t>()); +        return; +      case DSP_PROP_FREQ_SHIFT:{              double new_freq = val.as<double>();              _iface->poke32(UE_REG_DSP_RX_FREQ, @@ -143,10 +143,6 @@ void usrp_e100_impl::tx_duc_get(const wax::obj &key_, wax::obj &val){          val = _duc_freq;          return; -    case DSP_PROP_FREQ_SHIFT_NAMES: -        val = prop_names_t(1, ""); -        return; -      case DSP_PROP_CODEC_RATE:          val = _clock_ctrl->get_fpga_clock_rate();          return; diff --git a/host/lib/usrp/usrp_e100/fpga_downloader.cpp b/host/lib/usrp/usrp_e100/fpga_downloader.cpp index c0013fcbd..018a120d6 100644 --- a/host/lib/usrp/usrp_e100/fpga_downloader.cpp +++ b/host/lib/usrp/usrp_e100/fpga_downloader.cpp @@ -16,14 +16,21 @@  //  #include <uhd/config.hpp> -#include <uhd/utils/assert.hpp> +#ifdef UHD_DLL_EXPORTS +#include <uhd/exception.hpp> +#else //special case when this file is externally included +#include <stdexcept> +namespace uhd{ +    typedef std::runtime_error os_error; +    typedef std::runtime_error io_error; +} +#endif  #include <iostream>  #include <sstream>  #include <fstream>  #include <string>  #include <cstdlib> -#include <stdexcept>  #include <fcntl.h>  #include <sys/types.h> @@ -88,7 +95,7 @@ gpio::gpio(unsigned int gpio_num, gpio_direction pin_direction)  	std::fstream export_file;  	export_file.open("/sys/class/gpio/export", std::ios::out); -	if (not export_file.is_open()) throw std::runtime_error( +	if (not export_file.is_open()) throw uhd::os_error(  		"Failed to open gpio export file."  	); @@ -212,7 +219,7 @@ static void send_file_to_fpga(const std::string &file_name, gpio &error, gpio &d  	std::ifstream bitstream;  	bitstream.open(file_name.c_str(), std::ios::binary); -	if (!bitstream.is_open()) throw std::runtime_error( +	if (!bitstream.is_open()) throw uhd::os_error(  		"Coult not open the file: " + file_name  	); diff --git a/host/lib/usrp/usrp_e100/mboard_impl.cpp b/host/lib/usrp/usrp_e100/mboard_impl.cpp index 0e08cd435..cec4fd0ad 100644 --- a/host/lib/usrp/usrp_e100/mboard_impl.cpp +++ b/host/lib/usrp/usrp_e100/mboard_impl.cpp @@ -17,9 +17,9 @@  #include "usrp_e100_impl.hpp"  #include "usrp_e100_regs.hpp" +#include <uhd/exception.hpp>  #include <uhd/usrp/dsp_utils.hpp>  #include <uhd/usrp/misc_utils.hpp> -#include <uhd/utils/assert.hpp>  #include <uhd/usrp/mboard_props.hpp>  #include <boost/bind.hpp>  #include <iostream> @@ -53,7 +53,7 @@ void usrp_e100_impl::update_clock_config(void){      switch(_clock_config.pps_polarity){      case clock_config_t::PPS_POS: pps_flags |= UE_FLAG_TIME64_PPS_POSEDGE; break;      case clock_config_t::PPS_NEG: pps_flags |= UE_FLAG_TIME64_PPS_NEGEDGE; break; -    default: throw std::runtime_error("unhandled clock configuration pps polarity"); +    default: throw uhd::value_error("unhandled clock configuration pps polarity");      }      //set the pps flags @@ -64,7 +64,7 @@ void usrp_e100_impl::update_clock_config(void){      case clock_config_t::REF_AUTO: _clock_ctrl->use_auto_ref(); break;      case clock_config_t::REF_INT: _clock_ctrl->use_internal_ref(); break;      case clock_config_t::REF_SMA: _clock_ctrl->use_auto_ref(); break; -    default: throw std::runtime_error("unhandled clock configuration ref source"); +    default: throw uhd::value_error("unhandled clock configuration ref source");      }  } @@ -167,10 +167,6 @@ void usrp_e100_impl::mboard_set(const wax::obj &key, const wax::obj &val){      //handle the get request conditioned on the key      switch(key.as<mboard_prop_t>()){ -    case MBOARD_PROP_STREAM_CMD: -        issue_stream_cmd(val.as<stream_cmd_t>()); -        return; -      case MBOARD_PROP_TIME_NOW:      case MBOARD_PROP_TIME_PPS:{              time_spec_t time_spec = val.as<time_spec_t>(); diff --git a/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp b/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp index c13e880f3..ec0baf490 100644 --- a/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp +++ b/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp @@ -17,7 +17,7 @@  #include "usrp_e100_iface.hpp"  #include "usrp_e100_regs.hpp" -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp>  #include <sys/ioctl.h> //ioctl  #include <fcntl.h> //open, close  #include <linux/usrp_e.h> //ioctl structures and constants @@ -37,7 +37,7 @@ class i2c_dev_iface : public i2c_iface{  public:      i2c_dev_iface(const std::string &node){          if ((_node_fd = ::open(node.c_str(), O_RDWR)) < 0){ -            throw std::runtime_error("Failed to open " + node); +            throw uhd::io_error("Failed to open " + node);          }      } @@ -106,12 +106,9 @@ public:      {          //open the device node and check file descriptor          if ((_node_fd = ::open(node.c_str(), O_RDWR)) < 0){ -            throw std::runtime_error("Failed to open " + node); +            throw uhd::io_error("Failed to open " + node);          } -        //very first thing, reset all the wishbone, always do first! -        //disabled for now: this->poke32(UE_REG_CLEAR_GLOBAL, 0); -          mb_eeprom = mboard_eeprom_t(get_i2c_dev_iface(), mboard_eeprom_t::MAP_E100);      } @@ -127,7 +124,7 @@ public:          boost::mutex::scoped_lock lock(_ctrl_mutex);          if (::ioctl(_node_fd, request, mem) < 0){ -            throw std::runtime_error(str( +            throw uhd::os_error(str(                  boost::format("ioctl failed with request %d") % request              ));          } @@ -257,6 +254,14 @@ public:          //unload the data          return data.data;      } +     +    void write_uart(boost::uint8_t, const std::string &) { +        throw uhd::not_implemented_error("Unhandled command write_uart()"); +    } +     +    std::string read_uart(boost::uint8_t) { +        throw uhd::not_implemented_error("Unhandled command read_uart()"); +    }  private:      int _node_fd; diff --git a/host/lib/usrp/usrp_e100/usrp_e100_iface.hpp b/host/lib/usrp/usrp_e100/usrp_e100_iface.hpp index 12283fb52..cb0ca2dd4 100644 --- a/host/lib/usrp/usrp_e100/usrp_e100_iface.hpp +++ b/host/lib/usrp/usrp_e100/usrp_e100_iface.hpp @@ -24,6 +24,7 @@  #include <boost/shared_ptr.hpp>  #include <boost/utility.hpp>  #include <boost/cstdint.hpp> +#include <uhd/usrp/mboard_iface.hpp>  ////////////////////////////////////////////////////////////////////////  // I2C addresses @@ -39,7 +40,7 @@   * Provides a set of functions to implementation layer.   * Including spi, peek, poke, control...   */ -class usrp_e100_iface : boost::noncopyable, public uhd::i2c_iface{ +class usrp_e100_iface : boost::noncopyable, public uhd::usrp::mboard_iface{  public:      typedef boost::shared_ptr<usrp_e100_iface> sptr; @@ -67,51 +68,6 @@ public:      //! Get the I2C interface for the I2C device node      virtual uhd::i2c_iface &get_i2c_dev_iface(void) = 0; -    /*! -     * Write a register (32 bits) -     * \param addr the address -     * \param data the 32bit data -     */ -    virtual void poke32(boost::uint32_t addr, boost::uint32_t data) = 0; - -    /*! -     * Read a register (32 bits) -     * \param addr the address -     * \return the 32bit data -     */ -    virtual boost::uint32_t peek32(boost::uint32_t addr) = 0; - -    /*! -     * Write a register (16 bits) -     * \param addr the address -     * \param data the 16bit data -     */ -    virtual void poke16(boost::uint32_t addr, boost::uint16_t data) = 0; - -    /*! -     * Read a register (16 bits) -     * \param addr the address -     * \return the 16bit data -     */ -    virtual boost::uint16_t peek16(boost::uint32_t addr) = 0; - -    /*! -     * Perform an spi transaction. -     * \param which_slave the slave device number -     * \param config spi config args -     * \param data the bits to write -     * \param num_bits how many bits in data -     * \param readback true to readback a value -     * \return spi data if readback set -     */ -    virtual boost::uint32_t transact_spi( -        int which_slave, -        const uhd::spi_config_t &config, -        boost::uint32_t data, -        size_t num_bits, -        bool readback -    ) = 0; -      //motherboard eeprom map structure      uhd::usrp::mboard_eeprom_t mb_eeprom;  }; diff --git a/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp b/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp index 40ea56466..a120c3303 100644 --- a/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp +++ b/host/lib/usrp/usrp_e100/usrp_e100_impl.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 @@ -19,7 +19,7 @@  #include "usrp_e100_regs.hpp"  #include <uhd/usrp/device_props.hpp>  #include <uhd/usrp/mboard_props.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp>  #include <uhd/utils/static.hpp>  #include <uhd/utils/images.hpp>  #include <uhd/utils/warning.hpp> @@ -53,7 +53,7 @@ static device_addrs_t usrp_e100_find(const device_addr_t &hint){      if (fs::exists(hint["node"])){          device_addr_t new_addr;          new_addr["type"] = "usrp-e"; -        new_addr["node"] = fs::system_complete(fs::path(hint["node"])).file_string(); +        new_addr["node"] = fs::system_complete(fs::path(hint["node"])).string();          try{              usrp_e100_iface::sptr iface = usrp_e100_iface::make(new_addr["node"]);              new_addr["name"] = iface->mb_eeprom["name"]; @@ -103,7 +103,7 @@ static device::sptr usrp_e100_make(const device_addr_t &device_addr){      size_t fpga_hash = 0;      {          std::ifstream file(usrp_e100_fpga_image.c_str()); -        if (not file.good()) throw std::runtime_error( +        if (not file.good()) throw uhd::io_error(              "cannot open fpga file for read: " + usrp_e100_fpga_image          );          do{ @@ -132,7 +132,7 @@ static device::sptr usrp_e100_make(const device_addr_t &device_addr){      //check that the compatibility is correct      fpga_compat_num = iface->peek16(UE_REG_MISC_COMPAT);      if (fpga_compat_num != USRP_E_COMPAT_NUM){ -        throw std::runtime_error(str(boost::format( +        throw uhd::runtime_error(str(boost::format(              "Expected fpga compatibility number 0x%x, but got 0x%x:\n"              "The fpga build is not compatible with the host code build."          ) % USRP_E_COMPAT_NUM % fpga_compat_num)); diff --git a/host/lib/usrp/usrp_e100/usrp_e100_mmap_zero_copy.cpp b/host/lib/usrp/usrp_e100/usrp_e100_mmap_zero_copy.cpp index c155d426a..f4274dc5a 100644 --- a/host/lib/usrp/usrp_e100/usrp_e100_mmap_zero_copy.cpp +++ b/host/lib/usrp/usrp_e100/usrp_e100_mmap_zero_copy.cpp @@ -17,7 +17,7 @@  #include "usrp_e100_iface.hpp"  #include <uhd/transport/zero_copy.hpp> -#include <uhd/utils/assert.hpp> +#include <uhd/exception.hpp>  #include <linux/usrp_e.h>  #include <sys/mman.h> //mmap  #include <unistd.h> //getpagesize diff --git a/host/lib/usrp/usrp_e100/usrp_e100_regs.hpp b/host/lib/usrp/usrp_e100/usrp_e100_regs.hpp index a030462d0..1bcae64c7 100644 --- a/host/lib/usrp/usrp_e100/usrp_e100_regs.hpp +++ b/host/lib/usrp/usrp_e100/usrp_e100_regs.hpp @@ -131,7 +131,6 @@  #define UE_REG_CLEAR_ADDR(n)      (UE_REG_SETTINGS_BASE_ADDR(48) + (4*(n)))  #define UE_REG_CLEAR_RX           UE_REG_CLEAR_ADDR(0)  #define UE_REG_CLEAR_TX           UE_REG_CLEAR_ADDR(1) -#define UE_REG_CLEAR_GLOBAL       UE_REG_CLEAR_ADDR(2)  /////////////////////////////////////////////////  // DSP RX Regs diff --git a/host/lib/usrp/wrapper_utils.hpp b/host/lib/usrp/wrapper_utils.hpp deleted file mode 100644 index a7b5c5da6..000000000 --- a/host/lib/usrp/wrapper_utils.hpp +++ /dev/null @@ -1,66 +0,0 @@ -// -// Copyright 2010 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/>. -// - -#ifndef INCLUDED_LIBUHD_USRP_WRAPPER_UTILS_HPP -#define INCLUDED_LIBUHD_USRP_WRAPPER_UTILS_HPP - -#include <uhd/wax.hpp> -#include <uhd/types/ranges.hpp> -#include <uhd/usrp/dsp_props.hpp> -#include <uhd/utils/warning.hpp> -#include <boost/format.hpp> -#include <cmath> - -static inline uhd::freq_range_t add_dsp_shift( -    const uhd::freq_range_t &range, -    wax::obj dsp -){ -    double codec_rate = dsp[uhd::usrp::DSP_PROP_CODEC_RATE].as<double>(); -    return uhd::freq_range_t(range.start() - codec_rate/2.0, range.stop() + codec_rate/2.0); -} - -static inline void do_samp_rate_warning_message( -    double target_rate, -    double actual_rate, -    const std::string &xx -){ -    static const double max_allowed_error = 1.0; //Sps -    if (std::abs(target_rate - actual_rate) > max_allowed_error){ -        uhd::warning::post(str(boost::format( -            "The hardware does not support the requested %s sample rate:\n" -            "Target sample rate: %f MSps\n" -            "Actual sample rate: %f MSps\n" -        ) % xx % (target_rate/1e6) % (actual_rate/1e6))); -    } -} - -static inline void do_tune_freq_warning_message( -    double target_freq, -    double actual_freq, -    const std::string &xx -){ -    static const double max_allowed_error = 1.0; //Hz -    if (std::abs(target_freq - actual_freq) > max_allowed_error){ -        uhd::warning::post(str(boost::format( -            "The hardware does not support the requested %s frequency:\n" -            "Target frequency: %f MHz\n" -            "Actual frequency: %f MHz\n" -        ) % xx % (target_freq/1e6) % (actual_freq/1e6))); -    } -} - -#endif /* INCLUDED_LIBUHD_USRP_WRAPPER_UTILS_HPP */ | 
