diff options
Diffstat (limited to 'host')
57 files changed, 2285 insertions, 757 deletions
| diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index bf8d71b21..f2725e4b3 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -68,7 +68,6 @@ IF(WIN32)      ADD_DEFINITIONS(-D_WIN32_WINNT=0x0501) #minimum version required is windows xp      ADD_DEFINITIONS(-DNOMINMAX) #disables stupidity and enables std::min and std::max      ADD_DEFINITIONS(-D_SCL_SECURE_NO_WARNINGS) #avoid warnings from boost::split -    ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS) #avoid warnings from std::getenv      ADD_DEFINITIONS(-DBOOST_ALL_DYN_LINK) #setup boost auto-linking in msvc  ENDIF(WIN32) @@ -76,7 +75,7 @@ ENDIF(WIN32)  # Setup Boost  ########################################################################  SET(Boost_ADDITIONAL_VERSIONS "1.42.0" "1.42") -FIND_PACKAGE(Boost 1.37 REQUIRED COMPONENTS +FIND_PACKAGE(Boost 1.36 REQUIRED COMPONENTS      date_time      filesystem      program_options diff --git a/host/docs/build.rst b/host/docs/build.rst index 81e61475e..d28682764 100644 --- a/host/docs/build.rst +++ b/host/docs/build.rst @@ -40,7 +40,7 @@ CMake  ^^^^^^^^^^^^^^^^  Boost  ^^^^^^^^^^^^^^^^ -* **Version:** at least 3.7 unix, at least 4.0 windows +* **Version:** at least 3.6 unix, at least 4.0 windows  * **Required for:** build time + run time  * **Download URL:** http://www.boost.org/users/download/  * **Download URL (windows installer):** http://www.boostpro.com/download diff --git a/host/docs/usrp2.rst b/host/docs/usrp2.rst index f4c36fb27..dfde06b27 100644 --- a/host/docs/usrp2.rst +++ b/host/docs/usrp2.rst @@ -117,6 +117,17 @@ Run the following commands:  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  Debugging networking problems  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +**Disable the firewall:** +If uhd_find_devices gives you nothing +but uhd_find_devices --args addr=192.168.10.2 yeilds a discovered device, +then your firewall may be blocking replies to UDP broadcast packets. + +**Ping the USRP2:** +The USRP2 will reply to icmp echo requests. +:: + +    ping 192.168.10.2 +  **Monitor the USRP2:**  You can read the serial port on the rear of the USRP2  to get debug verbose from the embedded microcontroller. diff --git a/host/include/uhd/config.hpp b/host/include/uhd/config.hpp index 941219ac7..32eafc89b 100644 --- a/host/include/uhd/config.hpp +++ b/host/include/uhd/config.hpp @@ -39,27 +39,23 @@  //define logical operators  #ifdef BOOST_MSVC -  #define not ! -  #define and && -  #define or || +    #include <ciso646>  #endif  // http://gcc.gnu.org/wiki/Visibility  // Generic helper definitions for shared library support -#if defined _WIN32 || defined __CYGWIN__ +#if defined(BOOST_HAS_DECLSPEC)      #define UHD_HELPER_DLL_IMPORT __declspec(dllimport)      #define UHD_HELPER_DLL_EXPORT __declspec(dllexport)      #define UHD_HELPER_DLL_LOCAL +#elif defined(__GNUG__) && __GNUG__ >= 4 +    #define UHD_HELPER_DLL_IMPORT __attribute__ ((visibility("default"))) +    #define UHD_HELPER_DLL_EXPORT __attribute__ ((visibility("default"))) +    #define UHD_HELPER_DLL_LOCAL  __attribute__ ((visibility("hidden")))  #else -    #if __GNUC__ >= 4 -        #define UHD_HELPER_DLL_IMPORT __attribute__ ((visibility("default"))) -        #define UHD_HELPER_DLL_EXPORT __attribute__ ((visibility("default"))) -        #define UHD_HELPER_DLL_LOCAL  __attribute__ ((visibility("hidden"))) -    #else -        #define UHD_HELPER_DLL_IMPORT -        #define UHD_HELPER_DLL_EXPORT -        #define UHD_HELPER_DLL_LOCAL -    #endif +    #define UHD_HELPER_DLL_IMPORT +    #define UHD_HELPER_DLL_EXPORT +    #define UHD_HELPER_DLL_LOCAL  #endif  // Now we use the generic helper definitions above to define UHD_API and UHD_LOCAL. diff --git a/host/include/uhd/transport/udp_zero_copy.hpp b/host/include/uhd/transport/udp_zero_copy.hpp index c74e6d7b7..525606a9f 100644 --- a/host/include/uhd/transport/udp_zero_copy.hpp +++ b/host/include/uhd/transport/udp_zero_copy.hpp @@ -50,23 +50,15 @@ public:       *       * \param addr a string representing the destination address       * \param port a string representing the destination port +     * \param recv_buff_size size in bytes for the recv buffer, 0 for automatic +     * \param send_buff_size size in bytes for the send buffer, 0 for automatic       */ -    static sptr make(const std::string &addr, const std::string &port); - -    /*! -     * Resize the the rx buffer size on the socket. -     * \param num_bytes the new size for the socket buffer -     * \return the actual number of bytes allowed by the OS -     */ -    virtual size_t resize_recv_buff_size(size_t num_bytes) = 0; - -    /*! -     * Resize the the tx buffer size on the socket. -     * \param num_bytes the new size for the socket buffer -     * \return the actual number of bytes allowed by the OS -     */ -    virtual size_t resize_send_buff_size(size_t num_bytes) = 0; - +    static sptr make( +        const std::string &addr, +        const std::string &port, +        size_t recv_buff_size = 0, +        size_t send_buff_size = 0 +    );  };  }} //namespace diff --git a/host/include/uhd/types/device_addr.hpp b/host/include/uhd/types/device_addr.hpp index e8da2a1ab..e359d9467 100644 --- a/host/include/uhd/types/device_addr.hpp +++ b/host/include/uhd/types/device_addr.hpp @@ -40,7 +40,7 @@ namespace uhd{       * An arguments string, is a way to represent a device address       * using a single string with delimiter characters.       * - Ex: addr=192.168.10.2 -     * - Ex: addr=192.168.10.2, rx_buff_size=1e6 +     * - Ex: addr=192.168.10.2, recv_buff_size=1e6       */      class UHD_API device_addr_t : public dict<std::string, std::string>{      public: @@ -51,17 +51,17 @@ namespace uhd{          device_addr_t(const std::string &args = "");          /*! -         * Convert a device address into a printable string. -         * \return string good for use with std::cout << +         * Convert a device address into a pretty print string. +         * \return a printable string representing the device address           */ -        std::string to_string(void) const; +        std::string to_pp_string(void) const;          /*!           * Convert the device address into an args string.           * The args string contains delimiter symbols.           * \return a string with delimiter markup           */ -        std::string to_args_str(void) const; +        std::string to_string(void) const;      };      //handy typedef for a vector of device addresses diff --git a/host/include/uhd/types/dict.hpp b/host/include/uhd/types/dict.hpp index c8fbc5a9f..b5fb11120 100644 --- a/host/include/uhd/types/dict.hpp +++ b/host/include/uhd/types/dict.hpp @@ -29,7 +29,7 @@ namespace uhd{      /*!       * A templated dictionary class with a python-like interface.       */ -    template <class Key, class Val> class dict{ +    template <typename Key, typename Val> class dict{      public:          typedef std::pair<Key, Val> pair_t; @@ -130,7 +130,7 @@ namespace uhd{              BOOST_FOREACH(pair_t &p, _map){                  if (p.first == key) return p.second;              } -            _map.push_back(pair_t(key, Val())); +            _map.push_back(std::make_pair(key, Val()));              return _map.back().second;          } diff --git a/host/include/uhd/usrp/dboard_base.hpp b/host/include/uhd/usrp/dboard_base.hpp index 2025760ee..28bf2ae66 100644 --- a/host/include/uhd/usrp/dboard_base.hpp +++ b/host/include/uhd/usrp/dboard_base.hpp @@ -22,7 +22,6 @@  #include <uhd/wax.hpp>  #include <boost/utility.hpp>  #include <boost/shared_ptr.hpp> -#include <boost/tuple/tuple.hpp>  #include <uhd/usrp/dboard_id.hpp>  #include <uhd/usrp/dboard_iface.hpp> @@ -35,13 +34,15 @@ namespace uhd{ namespace usrp{  class UHD_API dboard_base : boost::noncopyable{  public:      typedef boost::shared_ptr<dboard_base> sptr; -    //the constructor args consist of a subdev name, interface, and ids -    //derived classes should pass the args into the dboard_base class ctor -    //but should not have to deal with the internals of the args -    typedef boost::tuple<std::string, dboard_iface::sptr, dboard_id_t, dboard_id_t> ctor_args_t; +    /*! +     * An opaque type for the dboard constructor args. +     * Derived classes should pass the args into the base class, +     * but should not deal with the internals of the args. +     */ +    struct ctor_args_impl; typedef ctor_args_impl* ctor_args_t;      //structors -    dboard_base(ctor_args_t const&); +    dboard_base(ctor_args_t);      virtual ~dboard_base(void);      //interface @@ -57,9 +58,8 @@ protected:      dboard_id_t get_tx_id(void);  private: -    std::string               _subdev_name; -    dboard_iface::sptr        _dboard_iface; -    dboard_id_t               _rx_id, _tx_id; +    struct dboard_base_impl; +    dboard_base_impl *_impl;  };  /*! @@ -71,7 +71,7 @@ public:      /*!       * Create a new xcvr dboard object, override in subclasses.       */ -    xcvr_dboard_base(ctor_args_t const&); +    xcvr_dboard_base(ctor_args_t);      virtual ~xcvr_dboard_base(void);  }; @@ -85,7 +85,7 @@ public:      /*!       * Create a new rx dboard object, override in subclasses.       */ -    rx_dboard_base(ctor_args_t const&); +    rx_dboard_base(ctor_args_t);      virtual ~rx_dboard_base(void); @@ -103,7 +103,7 @@ public:      /*!       * Create a new rx dboard object, override in subclasses.       */ -    tx_dboard_base(ctor_args_t const&); +    tx_dboard_base(ctor_args_t);      virtual ~tx_dboard_base(void); diff --git a/host/include/uhd/usrp/dboard_id.hpp b/host/include/uhd/usrp/dboard_id.hpp index afacaf8ff..8b6eaf6bd 100644 --- a/host/include/uhd/usrp/dboard_id.hpp +++ b/host/include/uhd/usrp/dboard_id.hpp @@ -20,16 +20,70 @@  #include <uhd/config.hpp>  #include <boost/cstdint.hpp> +#include <boost/operators.hpp>  #include <string>  namespace uhd{ namespace usrp{ -typedef boost::uint16_t dboard_id_t; +    class UHD_API dboard_id_t : boost::equality_comparable1<dboard_id_t>{ +    public: +        /*! +         * Create a dboard id from an integer. +         * \param id the integer representation +         */ +        dboard_id_t(boost::uint16_t id = 0xffff); -namespace dboard_id{ -    static const dboard_id_t NONE = 0xffff; -    UHD_API std::string to_string(const dboard_id_t &id); -} +        /*! +         * Obtain a dboard id that represents no dboard. +         * \return the dboard id with the 0xffff id. +         */ +        static dboard_id_t none(void); + +        /*! +         * Create a new dboard id from an integer representation. +         * \param uint16 an unsigned 16 bit integer +         * \return a new dboard id containing the integer +         */ +        static dboard_id_t from_uint16(boost::uint16_t uint16); + +        /*! +         * Get the dboard id represented as an integer. +         * \return an unsigned 16 bit integer representation +         */ +        boost::uint16_t to_uint16(void) const; + +        /*! +         * Create a new dboard id from a string representation. +         * If the string has a 0x prefix, it will be parsed as hex. +         * \param string a numeric string, possibly hex +         * \return a new dboard id containing the integer +         */ +        static dboard_id_t from_string(const std::string &string); + +        /*! +         * Get the dboard id represented as an integer. +         * \return a hex string representation with 0x prefix +         */ +        std::string to_string(void) const; + +        /*! +         * Get the pretty print representation of this dboard id. +         * \return a string with the dboard name and id number +         */ +        std::string to_pp_string(void) const; + +    private: +        boost::uint16_t _id; //internal representation +    }; + +    /*! +     * Comparator operator overloaded for dboard ids. +     * The boost::equality_comparable provides the !=. +     * \param lhs the dboard id to the left of the operator +     * \param rhs the dboard id to the right of the operator +     * \return true when the dboard ids are equal +     */ +    UHD_API bool operator==(const dboard_id_t &lhs, const dboard_id_t &rhs);  }} //namespace diff --git a/host/include/uhd/usrp/dboard_manager.hpp b/host/include/uhd/usrp/dboard_manager.hpp index 007d85bb4..b84fee4e7 100644 --- a/host/include/uhd/usrp/dboard_manager.hpp +++ b/host/include/uhd/usrp/dboard_manager.hpp @@ -37,7 +37,7 @@ public:      typedef boost::shared_ptr<dboard_manager> sptr;      //dboard constructor (each dboard should have a ::make with this signature) -    typedef dboard_base::sptr(*dboard_ctor_t)(dboard_base::ctor_args_t const&); +    typedef dboard_base::sptr(*dboard_ctor_t)(dboard_base::ctor_args_t);      /*!       * Register a dboard into the system. diff --git a/host/include/uhd/utils/CMakeLists.txt b/host/include/uhd/utils/CMakeLists.txt index 2831ab0b0..f588c6310 100644 --- a/host/include/uhd/utils/CMakeLists.txt +++ b/host/include/uhd/utils/CMakeLists.txt @@ -18,6 +18,7 @@  INSTALL(FILES      algorithm.hpp      assert.hpp +    exception.hpp      gain_handler.hpp      props.hpp      safe_main.hpp diff --git a/host/include/uhd/utils/algorithm.hpp b/host/include/uhd/utils/algorithm.hpp index 8fe9cde82..72b655745 100644 --- a/host/include/uhd/utils/algorithm.hpp +++ b/host/include/uhd/utils/algorithm.hpp @@ -19,43 +19,25 @@  #define INCLUDED_UHD_UTILS_ALGORITHM_HPP  #include <algorithm> +#include <boost/range/functions.hpp>  /*!   * Useful templated functions and classes that I like to pretend are part of stl   */  namespace std{ -    template<class T, class InputIterator, class Function> -    T reduce(InputIterator first, InputIterator last, Function fcn, T init = 0){ -        T tmp = init; -        for ( ; first != last; ++first ){ -            tmp = fcn(tmp, *first); -        } -        return tmp; +    template<typename Range, typename T> inline +    bool has(const Range &range, const T &value){ +        return boost::end(range) != std::find(boost::begin(range), boost::end(range), value);      } -    template<class T, class Iterable, class Function> -    T reduce(Iterable iterable, Function fcn, T init = 0){ -        return reduce(iterable.begin(), iterable.end(), fcn, init); -    } - -    template<class T, class InputIterator> -    bool has(InputIterator first, InputIterator last, const T &elem){ -        return last != std::find(first, last, elem); -    } - -    template<class T, class Iterable> -    bool has(const Iterable &iterable, const T &elem){ -        return has(iterable.begin(), iterable.end(), elem); -    } - -    template<class T> T signum(T n){ +    template<typename T> inline T signum(T n){          if (n < 0) return -1;          if (n > 0) return 1;          return 0;      } -    template<class T> T clip(T val, T minVal, T maxVal){ +    template<typename T> inline T clip(T val, T minVal, T maxVal){          return std::min(std::max(val, minVal), maxVal);      } diff --git a/host/include/uhd/utils/assert.hpp b/host/include/uhd/utils/assert.hpp index 01beed757..2f0ed4ff1 100644 --- a/host/include/uhd/utils/assert.hpp +++ b/host/include/uhd/utils/assert.hpp @@ -19,26 +19,24 @@  #define INCLUDED_UHD_UTILS_ASSERT_HPP  #include <uhd/config.hpp> +#include <uhd/utils/exception.hpp>  #include <uhd/utils/algorithm.hpp>  #include <boost/format.hpp>  #include <boost/foreach.hpp>  #include <boost/lexical_cast.hpp> -#include <boost/throw_exception.hpp> -#include <boost/exception/info.hpp>  #include <stdexcept>  #include <string>  namespace uhd{      //! The exception to throw when assertions fail -    struct UHD_API assert_error : virtual std::exception, virtual boost::exception{}; - -    //! The assertion info, the code that failed -    typedef boost::error_info<struct tag_assert_info, std::string> assert_info; +    struct UHD_API assert_error : std::runtime_error{ +        assert_error(const std::string &what); +    };      //! Throw an assert error with throw-site information      #define UHD_ASSERT_THROW(_x) if (not (_x)) \ -        BOOST_THROW_EXCEPTION(uhd::assert_error() << uhd::assert_info(#_x)) +        throw uhd::assert_error(UHD_THROW_SITE_INFO("assertion failed: " + std::string(#_x)))      /*!       * Check that an element is found in a container. @@ -46,30 +44,31 @@ namespace uhd{       * The "what" in the error will show what is       * being set and a list of known good values.       * -     * \param iterable a list of possible settings -     * \param elem an element that may be in the list +     * \param range a list of possible settings +     * \param value an element that may be in the list       * \param what a description of what is being set       * \throw assertion_error when elem not in list       */ -    template<class T, class Iterable> void assert_has( -        const Iterable &iterable, -        const T &elem, +    template<typename T, typename Range> void assert_has( +        const Range &range, +        const T &value,          const std::string &what = "unknown"      ){ -        if (std::has(iterable, elem)) return; +        if (std::has(range, value)) return;          std::string possible_values = "";          size_t i = 0; -        BOOST_FOREACH(const T &e, iterable){ +        BOOST_FOREACH(const T &v, range){              if (i++ > 0) possible_values += ", "; -            possible_values += boost::lexical_cast<std::string>(e); +            possible_values += boost::lexical_cast<std::string>(v);          } -        boost::throw_exception(uhd::assert_error() << assert_info(str(boost::format( -                "Error: %s is not a valid %s. " -                "Possible values are: [%s]." +        throw uhd::assert_error(str(boost::format( +                "assertion failed:\n" +                "  %s is not a valid %s.\n" +                "  possible values are: [%s].\n"              ) -            % boost::lexical_cast<std::string>(elem) +            % boost::lexical_cast<std::string>(value)              % what % possible_values -        ))); +        ));      }  }//namespace uhd diff --git a/host/include/uhd/utils/exception.hpp b/host/include/uhd/utils/exception.hpp new file mode 100644 index 000000000..40e81fae0 --- /dev/null +++ b/host/include/uhd/utils/exception.hpp @@ -0,0 +1,38 @@ +// +// 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_UHD_UTILS_EXCEPTION_HPP +#define INCLUDED_UHD_UTILS_EXCEPTION_HPP + +#include <uhd/config.hpp> +#include <boost/current_function.hpp> +#include <stdexcept> +#include <string> + +/*! + * Create a formated string with throw-site information. + * Fills in the function name, file name, and line number. + * \param what the std::exeption message + * \return the formatted exception message + */ +#define UHD_THROW_SITE_INFO(what) std::string( \ +    std::string(what) + "\n" + \ +    "  in " + std::string(BOOST_CURRENT_FUNCTION) + "\n" + \ +    "  at " + std::string(__FILE__) + ":" + BOOST_STRINGIZE(__LINE__) + "\n" \ +) + +#endif /* INCLUDED_UHD_UTILS_EXCEPTION_HPP */ diff --git a/host/include/uhd/utils/props.hpp b/host/include/uhd/utils/props.hpp index 516102a5f..f376d2612 100644 --- a/host/include/uhd/utils/props.hpp +++ b/host/include/uhd/utils/props.hpp @@ -20,9 +20,8 @@  #include <uhd/config.hpp>  #include <uhd/wax.hpp> +#include <uhd/utils/exception.hpp>  #include <boost/tuple/tuple.hpp> -#include <boost/throw_exception.hpp> -#include <boost/exception/info.hpp>  #include <stdexcept>  #include <vector>  #include <string> @@ -59,25 +58,19 @@ namespace uhd{          const std::string &name = ""      ); -    //! The exception to throw for property errors -    struct UHD_API prop_error : virtual std::exception, virtual boost::exception{}; - -    //! The property error info (verbose or message) -    typedef boost::error_info<struct tag_prop_info, std::string> prop_info; -      /*!       * Throw when getting a not-implemented or write-only property.       * Throw-site information will be included with this error.       */      #define UHD_THROW_PROP_GET_ERROR() \ -        BOOST_THROW_EXCEPTION(uhd::prop_error() << uhd::prop_info("cannot get this property")) +        throw std::runtime_error(UHD_THROW_SITE_INFO("cannot get this property"))      /*!       * Throw when setting a not-implemented or read-only property.       * Throw-site information will be included with this error.       */      #define UHD_THROW_PROP_SET_ERROR() \ -        BOOST_THROW_EXCEPTION(uhd::prop_error() << uhd::prop_info("cannot set this property")) +        throw std::runtime_error(UHD_THROW_SITE_INFO("cannot set this property"))  } //namespace uhd diff --git a/host/include/uhd/utils/safe_main.hpp b/host/include/uhd/utils/safe_main.hpp index a4e4e06e8..b682aa540 100644 --- a/host/include/uhd/utils/safe_main.hpp +++ b/host/include/uhd/utils/safe_main.hpp @@ -19,7 +19,6 @@  #define INCLUDED_UHD_UTILS_SAFE_MAIN_HPP  #include <uhd/config.hpp> -#include <boost/exception/diagnostic_information.hpp>  #include <iostream>  #include <stdexcept> @@ -34,8 +33,6 @@  int main(int argc, char *argv[]){ \      try { \          return _main(argc, argv); \ -    } catch(const boost::exception &e){ \ -        std::cerr << "Error: " << boost::diagnostic_information(e) << std::endl; \      } catch(const std::exception &e) { \          std::cerr << "Error: " << e.what() << std::endl; \      } catch(...) { \ diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index 5252eda8f..7b765b0d3 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -15,7 +15,6 @@  # along with this program.  If not, see <http://www.gnu.org/licenses/>.  # -  ########################################################################  # Setup Python  ######################################################################## @@ -43,29 +42,13 @@ IF(NOT HAVE_PYTHON_MODULE_CHEETAH)  ENDIF(NOT HAVE_PYTHON_MODULE_CHEETAH)  ######################################################################## -# Create a list of libuhd sources +# Helpful Macros  ######################################################################## -SET(libuhd_sources -    device.cpp -    gain_handler.cpp -    load_modules.cpp -    types.cpp -    utils.cpp -    wax.cpp -    transport/convert_types.cpp -    transport/if_addrs.cpp -    transport/udp_simple.cpp -    usrp/dboard_base.cpp -    usrp/dboard_eeprom.cpp -    usrp/simple_usrp.cpp -    usrp/dboard_manager.cpp -    usrp/tune_helper.cpp -) +MACRO(LIBUHD_APPEND_SOURCES) +    LIST(APPEND libuhd_sources ${ARGV}) +ENDMACRO(LIBUHD_APPEND_SOURCES) -######################################################################## -# Generate Files -######################################################################## -MACRO(UHD_PYTHON_GEN_SOURCE_FILE pyfile outfile) +MACRO(LIBUHD_PYTHON_GEN_SOURCE pyfile outfile)      #ensure that the directory exists for outfile      GET_FILENAME_COMPONENT(outfile_dir ${outfile} PATH)      FILE(MAKE_DIRECTORY ${outfile_dir}) @@ -78,75 +61,17 @@ MACRO(UHD_PYTHON_GEN_SOURCE_FILE pyfile outfile)      )      #make libuhd depend on the outfile -    LIST(APPEND libuhd_sources ${outfile}) -ENDMACRO(UHD_PYTHON_GEN_SOURCE_FILE) - -UHD_PYTHON_GEN_SOURCE_FILE( -    ${CMAKE_CURRENT_SOURCE_DIR}/transport/gen_vrt.py -    ${CMAKE_CURRENT_BINARY_DIR}/transport/vrt.cpp -) - -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/ic_reg_maps) - -UHD_PYTHON_GEN_SOURCE_FILE( -    ${CMAKE_CURRENT_SOURCE_DIR}/ic_reg_maps/gen_adf4360_regs.py -    ${CMAKE_CURRENT_BINARY_DIR}/ic_reg_maps/adf4360_regs.hpp -) - -UHD_PYTHON_GEN_SOURCE_FILE( -    ${CMAKE_CURRENT_SOURCE_DIR}/ic_reg_maps/gen_ad9510_regs.py -    ${CMAKE_CURRENT_BINARY_DIR}/ic_reg_maps/ad9510_regs.hpp -) - -UHD_PYTHON_GEN_SOURCE_FILE( -    ${CMAKE_CURRENT_SOURCE_DIR}/ic_reg_maps/gen_ad9777_regs.py -    ${CMAKE_CURRENT_BINARY_DIR}/ic_reg_maps/ad9777_regs.hpp -) - -UHD_PYTHON_GEN_SOURCE_FILE( -    ${CMAKE_CURRENT_SOURCE_DIR}/ic_reg_maps/gen_ad5624_regs.py -    ${CMAKE_CURRENT_BINARY_DIR}/ic_reg_maps/ad5624_regs.hpp -) +    LIBUHD_APPEND_SOURCES(${outfile}) +ENDMACRO(LIBUHD_PYTHON_GEN_SOURCE) -UHD_PYTHON_GEN_SOURCE_FILE( -    ${CMAKE_CURRENT_SOURCE_DIR}/ic_reg_maps/gen_ad7922_regs.py -    ${CMAKE_CURRENT_BINARY_DIR}/ic_reg_maps/ad7922_regs.hpp -) - -UHD_PYTHON_GEN_SOURCE_FILE( -    ${CMAKE_CURRENT_SOURCE_DIR}/ic_reg_maps/gen_max2829_regs.py -    ${CMAKE_CURRENT_BINARY_DIR}/ic_reg_maps/max2829_regs.hpp -) - -######################################################################## -# Add dboard sources  ######################################################################## -LIST(APPEND libuhd_sources -    usrp/dboard/db_basic_and_lf.cpp -    usrp/dboard/db_rfx.cpp -    usrp/dboard/db_xcvr2450.cpp -) - +# Include CMakeLists.txt from subdirectories  ######################################################################## -# Add usrp2 sources -######################################################################## -LIST(APPEND libuhd_sources -    usrp/usrp2/clock_control.cpp -    usrp/usrp2/dboard_impl.cpp -    usrp/usrp2/dboard_iface.cpp -    usrp/usrp2/dsp_impl.cpp -    usrp/usrp2/io_impl.cpp -    usrp/usrp2/mboard_impl.cpp -    usrp/usrp2/usrp2_iface.cpp -    usrp/usrp2/usrp2_impl.cpp -) - -######################################################################## -# Conditionally add the udp sources -######################################################################## -LIST(APPEND libuhd_sources -    transport/udp_zero_copy_asio.cpp -) +INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/ic_reg_maps/CMakeLists.txt) +INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/transport/CMakeLists.txt) +INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/usrp/CMakeLists.txt) +INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/usrp/dboard/CMakeLists.txt) +INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/usrp/usrp2/CMakeLists.txt)  ########################################################################  # Setup defines for module loading @@ -168,23 +93,16 @@ ELSE(HAVE_DLFCN_H)  ENDIF(HAVE_DLFCN_H)  ######################################################################## -# Setup defines for interface address discovery +# Append to the list of sources for lib uhd  ######################################################################## -MESSAGE(STATUS "Configuring interface address discovery...") - -INCLUDE(CheckIncludeFileCXX) -CHECK_INCLUDE_FILE_CXX(ifaddrs.h HAVE_IFADDRS_H) -CHECK_INCLUDE_FILE_CXX(winsock2.h HAVE_WINSOCK2_H) - -IF(HAVE_IFADDRS_H) -    MESSAGE(STATUS "  Interface address discovery supported through getifaddrs.") -    ADD_DEFINITIONS(-DHAVE_IFADDRS_H) -ELSEIF(HAVE_WINSOCK2_H) -    MESSAGE(STATUS "  Interface address discovery supported through SIO_GET_INTERFACE_LIST.") -    ADD_DEFINITIONS(-DHAVE_WINSOCK2_H) -ELSE(HAVE_IFADDRS_H) -    MESSAGE(STATUS "  Interface address discovery not supported.") -ENDIF(HAVE_IFADDRS_H) +LIBUHD_APPEND_SOURCES( +    ${CMAKE_CURRENT_SOURCE_DIR}/device.cpp +    ${CMAKE_CURRENT_SOURCE_DIR}/gain_handler.cpp +    ${CMAKE_CURRENT_SOURCE_DIR}/load_modules.cpp +    ${CMAKE_CURRENT_SOURCE_DIR}/types.cpp +    ${CMAKE_CURRENT_SOURCE_DIR}/utils.cpp +    ${CMAKE_CURRENT_SOURCE_DIR}/wax.cpp +)  ########################################################################  # Setup libuhd library diff --git a/host/lib/device.cpp b/host/lib/device.cpp index 88bd2cff4..f139ecb20 100644 --- a/host/lib/device.cpp +++ b/host/lib/device.cpp @@ -105,14 +105,14 @@ device::sptr device::make(const device_addr_t &hint, size_t which){      //check that we found any devices      if (dev_addr_makers.size() == 0){          throw std::runtime_error(str( -            boost::format("No devices found for ----->\n%s") % hint.to_string() +            boost::format("No devices found for ----->\n%s") % hint.to_pp_string()          ));      }      //check that the which index is valid      if (dev_addr_makers.size() <= which){          throw std::runtime_error(str( -            boost::format("No device at index %d for ----->\n%s") % which % hint.to_string() +            boost::format("No device at index %d for ----->\n%s") % which % hint.to_pp_string()          ));      } diff --git a/host/lib/ic_reg_maps/CMakeLists.txt b/host/lib/ic_reg_maps/CMakeLists.txt new file mode 100644 index 000000000..63378eb89 --- /dev/null +++ b/host/lib/ic_reg_maps/CMakeLists.txt @@ -0,0 +1,65 @@ +# +# 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/>. +# + +#This file will be included by cmake, use absolute paths! + +INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/lib/ic_reg_maps) + +LIBUHD_PYTHON_GEN_SOURCE( +    ${CMAKE_SOURCE_DIR}/lib/ic_reg_maps/gen_adf4350_regs.py +    ${CMAKE_BINARY_DIR}/lib/ic_reg_maps/adf4350_regs.hpp +) + +LIBUHD_PYTHON_GEN_SOURCE( +    ${CMAKE_SOURCE_DIR}/lib/ic_reg_maps/gen_adf4360_regs.py +    ${CMAKE_BINARY_DIR}/lib/ic_reg_maps/adf4360_regs.hpp +) + +LIBUHD_PYTHON_GEN_SOURCE( +    ${CMAKE_SOURCE_DIR}/lib/ic_reg_maps/gen_ad9510_regs.py +    ${CMAKE_BINARY_DIR}/lib/ic_reg_maps/ad9510_regs.hpp +) + +LIBUHD_PYTHON_GEN_SOURCE( +    ${CMAKE_SOURCE_DIR}/lib/ic_reg_maps/gen_ad9777_regs.py +    ${CMAKE_BINARY_DIR}/lib/ic_reg_maps/ad9777_regs.hpp +) + +LIBUHD_PYTHON_GEN_SOURCE( +    ${CMAKE_SOURCE_DIR}/lib/ic_reg_maps/gen_ad5624_regs.py +    ${CMAKE_BINARY_DIR}/lib/ic_reg_maps/ad5624_regs.hpp +) + +LIBUHD_PYTHON_GEN_SOURCE( +    ${CMAKE_SOURCE_DIR}/lib/ic_reg_maps/gen_ad7922_regs.py +    ${CMAKE_BINARY_DIR}/lib/ic_reg_maps/ad7922_regs.hpp +) + +LIBUHD_PYTHON_GEN_SOURCE( +    ${CMAKE_SOURCE_DIR}/lib/ic_reg_maps/gen_max2829_regs.py +    ${CMAKE_BINARY_DIR}/lib/ic_reg_maps/max2829_regs.hpp +) + +LIBUHD_PYTHON_GEN_SOURCE( +    ${CMAKE_SOURCE_DIR}/lib/ic_reg_maps/gen_ad9862_regs.py +    ${CMAKE_BINARY_DIR}/lib/ic_reg_maps/ad9862_regs.hpp +) + +LIBUHD_PYTHON_GEN_SOURCE( +    ${CMAKE_SOURCE_DIR}/lib/ic_reg_maps/gen_ad9522_regs.py +    ${CMAKE_BINARY_DIR}/lib/ic_reg_maps/ad9522_regs.hpp +) diff --git a/host/lib/ic_reg_maps/common.py b/host/lib/ic_reg_maps/common.py index d05470706..e27c2816d 100644 --- a/host/lib/ic_reg_maps/common.py +++ b/host/lib/ic_reg_maps/common.py @@ -16,23 +16,98 @@  #  import re +import sys  import math  from Cheetah.Template import Template +COMMON_TMPL = """\ +#import time +/*********************************************************************** + * This file was generated by $file on $time.strftime("%c") + **********************************************************************/ + +\#ifndef INCLUDED_$(name.upper())_HPP +\#define INCLUDED_$(name.upper())_HPP + +\#include <uhd/config.hpp> +\#include <boost/cstdint.hpp> +\#include <stdexcept> +\#include <set> + +class $(name)_t{ +public: +    #for $reg in $regs +    #if $reg.get_enums() +    enum $reg.get_type(){ +        #for $i, $enum in enumerate($reg.get_enums()) +        #set $end_comma = ',' if $i < len($reg.get_enums())-1 else '' +        $(reg.get_name().upper())_$(enum[0].upper()) = $enum[1]$end_comma +        #end for +    }; +    #end if +    $reg.get_type() $reg.get_name(); +    #end for + +    $(name)_t(void){ +        _state = NULL; +        #for $reg in $regs +        $reg.get_name() = $reg.get_default(); +        #end for +    } + +    ~$(name)_t(void){ +        delete _state; +    } + +$body + +    void save_state(void){ +        if (_state == NULL) _state = new $(name)_t(); +        #for $reg in $regs +        _state->$reg.get_name() = this->$reg.get_name(); +        #end for +    } + +    template<typename T> std::set<T> get_changed_addrs(void){ +        if (_state == NULL) throw std::runtime_error("no saved state"); +        //check each register for changes +        std::set<T> addrs; +        #for $reg in $regs +        if(_state->$reg.get_name() != this->$reg.get_name()){ +            addrs.insert($reg.get_addr()); +        } +        #end for +        return addrs; +    } + +private: +    $(name)_t *_state; +}; + +\#endif /* INCLUDED_$(name.upper())_HPP */ +""" +  def parse_tmpl(_tmpl_text, **kwargs):      return str(Template(_tmpl_text, kwargs)) +def to_num(arg): return eval(arg) +  class reg:      def __init__(self, reg_des): +        try: self.parse(reg_des) +        except Exception, e: +            raise Exception, 'Error parsing register description: "%s"\nWhat: %s'%(reg_des, e) + +    def parse(self, reg_des):          x = re.match('^(\w*)\s*(\w*)\[(.*)\]\s*(\w*)\s*(.*)$', reg_des)          name, addr, bit_range, default, enums = x.groups()          #store variables          self._name = name -        self._addr = int(addr, 16) +        self._addr = to_num(addr)          if ':' in bit_range: self._addr_spec = sorted(map(int, bit_range.split(':')))          else: self._addr_spec = int(bit_range), int(bit_range) -        self._default = int(default, 16) +        self._default = to_num(default)          #extract enum          self._enums = list() @@ -41,7 +116,7 @@ class reg:              for enum_str in map(str.strip, enums.split(',')):                  if '=' in enum_str:                      enum_name, enum_val = enum_str.split('=') -                    enum_val = int(enum_val) +                    enum_val = to_num(enum_val)                  else: enum_name = enum_str                  self._enums.append((enum_name, enum_val))                  enum_val += 1 @@ -53,8 +128,20 @@ class reg:          for key, val in self.get_enums():              if val == self._default: return str.upper('%s_%s'%(self.get_name(), key))          return self._default -    def get_stdint_type(self):\ -        return 'uint%d_t'%max(2**math.ceil(math.log(self.get_bit_width(), 2)), 8) +    def get_type(self): +        if self.get_enums(): return '%s_t'%self.get_name() +        return 'boost::uint%d_t'%max(2**math.ceil(math.log(self.get_bit_width(), 2)), 8)      def get_shift(self): return self._addr_spec[0]      def get_mask(self): return hex(int('1'*self.get_bit_width(), 2))      def get_bit_width(self): return self._addr_spec[1] - self._addr_spec[0] + 1 + +def generate(name, regs_tmpl, body_tmpl='', file=__file__): +    regs = map(reg, parse_tmpl(regs_tmpl).splitlines()) +    body = parse_tmpl(body_tmpl, regs=regs).replace('\n', '\n    ').strip() +    code = parse_tmpl(COMMON_TMPL, +        name=name, +        regs=regs, +        body=body, +        file=file, +    ) +    open(sys.argv[1], 'w').write(code) diff --git a/host/lib/ic_reg_maps/gen_ad5624_regs.py b/host/lib/ic_reg_maps/gen_ad5624_regs.py index 9e8ae5be5..24401b878 100755 --- a/host/lib/ic_reg_maps/gen_ad5624_regs.py +++ b/host/lib/ic_reg_maps/gen_ad5624_regs.py @@ -16,67 +16,33 @@  # along with this program.  If not, see <http://www.gnu.org/licenses/>.  # -import sys -from common import * -  ########################################################################  # Template for raw text data describing registers  # name addr[bit range inclusive] default optional enums  ######################################################################## -REGS_DATA_TMPL="""\ +REGS_TMPL="""\  data             0[4:15]           0  addr             0[16:18]          0       DAC_A=0, DAC_B=1, DAC_C=2, DAC_D=3, ALL=7  cmd              0[19:21]          0       wr_input_n, up_dac_n, wr_input_n_up_all, wr_up_dac_chan_n, power_down, reset, load_ldac  """  ######################################################################## -# Header and Source templates below +# Template for methods in the body of the struct  ######################################################################## -HEADER_TEXT=""" -#import time - -/*********************************************************************** - * This file was generated by $file on $time.strftime("%c") - **********************************************************************/ - -\#ifndef INCLUDED_AD5624_REGS_HPP -\#define INCLUDED_AD5624_REGS_HPP - -\#include <boost/cstdint.hpp> - -struct ad5624_regs_t{ -#for $reg in $regs -    #if $reg.get_enums() -    enum $(reg.get_name())_t{ -        #for $i, $enum in enumerate($reg.get_enums()) -        #set $end_comma = ',' if $i < len($reg.get_enums())-1 else '' -        $(reg.get_name().upper())_$(enum[0].upper()) = $enum[1]$end_comma -        #end for -    } $reg.get_name(); -    #else -    boost::$reg.get_stdint_type() $reg.get_name(); -    #end if -#end for - -    ad5624_regs_t(void){ -#for $reg in $regs -        $reg.get_name() = $reg.get_default(); -#end for -    } - -    boost::uint32_t get_reg(void){ -        boost::uint32_t reg = 0; -        #for $reg in filter(lambda r: r.get_addr() == 0, $regs) -        reg |= (boost::uint32_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift(); -        #end for -        return reg; -    } - -}; - -\#endif /* INCLUDED_AD5624_REGS_HPP */ +BODY_TMPL="""\ +boost::uint32_t get_reg(void){ +    boost::uint32_t reg = 0; +    #for $reg in filter(lambda r: r.get_addr() == 0, $regs) +    reg |= (boost::uint32_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift(); +    #end for +    return reg; +}  """  if __name__ == '__main__': -    regs = map(reg, parse_tmpl(REGS_DATA_TMPL).splitlines()) -    open(sys.argv[1], 'w').write(parse_tmpl(HEADER_TEXT, regs=regs, file=__file__)) +    import common; common.generate( +        name='ad5624_regs', +        regs_tmpl=REGS_TMPL, +        body_tmpl=BODY_TMPL, +        file=__file__, +    ) diff --git a/host/lib/ic_reg_maps/gen_ad7922_regs.py b/host/lib/ic_reg_maps/gen_ad7922_regs.py index 23f28c0da..5cec1924a 100755 --- a/host/lib/ic_reg_maps/gen_ad7922_regs.py +++ b/host/lib/ic_reg_maps/gen_ad7922_regs.py @@ -16,73 +16,39 @@  # along with this program.  If not, see <http://www.gnu.org/licenses/>.  # -import sys -from common import * -  ########################################################################  # Template for raw text data describing registers  # name addr[bit range inclusive] default optional enums  ######################################################################## -REGS_DATA_TMPL="""\ +REGS_TMPL="""\  result           0[0:11]        0  mod              0[12]          0  chn              0[13]          0  """  ######################################################################## -# Header and Source templates below +# Template for methods in the body of the struct  ######################################################################## -HEADER_TEXT=""" -#import time - -/*********************************************************************** - * This file was generated by $file on $time.strftime("%c") - **********************************************************************/ - -\#ifndef INCLUDED_AD7922_REGS_HPP -\#define INCLUDED_AD7922_REGS_HPP - -\#include <boost/cstdint.hpp> - -struct ad7922_regs_t{ -#for $reg in $regs -    #if $reg.get_enums() -    enum $(reg.get_name())_t{ -        #for $i, $enum in enumerate($reg.get_enums()) -        #set $end_comma = ',' if $i < len($reg.get_enums())-1 else '' -        $(reg.get_name().upper())_$(enum[0].upper()) = $enum[1]$end_comma -        #end for -    } $reg.get_name(); -    #else -    boost::$reg.get_stdint_type() $reg.get_name(); -    #end if -#end for - -    ad7922_regs_t(void){ -#for $reg in $regs -        $reg.get_name() = $reg.get_default(); -#end for -    } - -    boost::uint16_t get_reg(void){ -        boost::uint16_t reg = 0; -        #for $reg in filter(lambda r: r.get_addr() == 0, $regs) -        reg |= (boost::uint32_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift(); -        #end for -        return reg; -    } - -    void set_reg(boost::uint16_t reg){ -        #for $reg in filter(lambda r: r.get_addr() == 0, $regs) -        $reg.get_name() = (reg >> $reg.get_shift()) & $reg.get_mask(); -        #end for -    } - -}; - -\#endif /* INCLUDED_AD7922_REGS_HPP */ +BODY_TMPL="""\ +boost::uint16_t get_reg(void){ +    boost::uint16_t reg = 0; +    #for $reg in filter(lambda r: r.get_addr() == 0, $regs) +    reg |= (boost::uint32_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift(); +    #end for +    return reg; +} + +void set_reg(boost::uint16_t reg){ +    #for $reg in filter(lambda r: r.get_addr() == 0, $regs) +    $reg.get_name() = $(reg.get_type())((reg >> $reg.get_shift()) & $reg.get_mask()); +    #end for +}  """  if __name__ == '__main__': -    regs = map(reg, parse_tmpl(REGS_DATA_TMPL).splitlines()) -    open(sys.argv[1], 'w').write(parse_tmpl(HEADER_TEXT, regs=regs, file=__file__)) +    import common; common.generate( +        name='ad7922_regs', +        regs_tmpl=REGS_TMPL, +        body_tmpl=BODY_TMPL, +        file=__file__, +    ) diff --git a/host/lib/ic_reg_maps/gen_ad9510_regs.py b/host/lib/ic_reg_maps/gen_ad9510_regs.py index 2dc19c691..83236c921 100755 --- a/host/lib/ic_reg_maps/gen_ad9510_regs.py +++ b/host/lib/ic_reg_maps/gen_ad9510_regs.py @@ -16,14 +16,11 @@  # along with this program.  If not, see <http://www.gnu.org/licenses/>.  # -import sys -from common import * -  ########################################################################  # Template for raw text data describing registers  # name addr[bit range inclusive] default optional enums  ######################################################################## -REGS_DATA_TMPL="""\ +REGS_TMPL="""\  ########################################################################  ## serial control port config  ######################################################################## @@ -46,14 +43,14 @@ reset_all_counters             9[0]          0  ncounter_reset                 9[1]          0  rcounter_reset                 9[2]          0  cp_current_setting             9[4:6]        0      0_60ma, 1_2ma, 1_8ma, 2_4ma, 3_0ma, 3_6ma, 4_2ma, 4_8ma -pll_power_down                 A[0:1]        0      normal=0, async_pd=1, sync_pd=3 -prescaler_value                A[2:4]        0      div1, div2, 2_3, 4_5, 8_9, 16_17, 32_33, div3 -b_counter_bypass               A[6]          0 -ref_counter_msb                B[0:5]        0 -ref_counter_lsb                C[0:7]        0 -antibacklash_pw                D[0:1]        0      1_3ns, 2_9ns, 6_0ns -dld_window                     D[5]          0      9_5ns, 3_5ns -lock_detect_disable            D[6]          0      enb, dis +pll_power_down                 0xA[0:1]      0      normal=0, async_pd=1, sync_pd=3 +prescaler_value                0xA[2:4]      0      div1, div2, 2_3, 4_5, 8_9, 16_17, 32_33, div3 +b_counter_bypass               0xA[6]        0 +ref_counter_msb                0xB[0:5]      0 +ref_counter_lsb                0xC[0:7]      0 +antibacklash_pw                0xD[0:1]      0      1_3ns, 2_9ns, 6_0ns +dld_window                     0xD[5]        0      9_5ns, 3_5ns +lock_detect_disable            0xD[6]        0      enb, dis  ########################################################################  ## fine delay adjust  ######################################################################## @@ -103,71 +100,40 @@ soft_sync                      58[2]               0  dist_power_down                58[3]               0  sync_power_down                58[4]               0  function_pin_select            58[5:6]             0    resetb, syncb, test, pdb -update_registers               5A[0]               0 +update_registers               0x5A[0]             0  """  ######################################################################## -# Header and Source templates below +# Template for methods in the body of the struct  ######################################################################## -HEADER_TEXT=""" -#import time - -/*********************************************************************** - * This file was generated by $file on $time.strftime("%c") - **********************************************************************/ - -\#ifndef INCLUDED_AD9510_REGS_HPP -\#define INCLUDED_AD9510_REGS_HPP - -\#include <boost/cstdint.hpp> - -struct ad9510_regs_t{ -#for $reg in $regs -    #if $reg.get_enums() -    enum $(reg.get_name())_t{ -        #for $i, $enum in enumerate($reg.get_enums()) -        #set $end_comma = ',' if $i < len($reg.get_enums())-1 else '' -        $(reg.get_name().upper())_$(enum[0].upper()) = $enum[1]$end_comma +BODY_TMPL="""\ +boost::uint8_t get_reg(boost::uint16_t addr){ +    boost::uint8_t reg = 0; +    switch(addr){ +    #for $addr in sorted(set(map(lambda r: r.get_addr(), $regs))) +    case $addr: +        #for $reg in filter(lambda r: r.get_addr() == addr, $regs) +        reg |= (boost::uint32_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift();          #end for -    } $reg.get_name(); -    #else -    boost::$reg.get_stdint_type() $reg.get_name(); -    #end if -#end for - -    ad9510_regs_t(void){ -#for $reg in $regs -        $reg.get_name() = $reg.get_default(); -#end for -    } - -    boost::uint8_t get_reg(boost::uint16_t addr){ -        boost::uint8_t reg = 0; -        switch(addr){ -        #for $addr in sorted(set(map(lambda r: r.get_addr(), $regs))) -        case $addr: -            #for $reg in filter(lambda r: r.get_addr() == addr, $regs) -            reg |= (boost::uint32_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift(); -            #end for -            break; -        #end for -        } -        return reg; -    } - -    boost::uint32_t get_write_reg(boost::uint16_t addr){ -        return (boost::uint32_t(addr) << 8) | get_reg(addr); -    } - -    boost::uint32_t get_read_reg(boost::uint16_t addr){ -        return (boost::uint32_t(addr) << 8) | (1 << 15); +        break; +    #end for      } +    return reg; +} -}; +boost::uint32_t get_write_reg(boost::uint16_t addr){ +    return (boost::uint32_t(addr) << 8) | get_reg(addr); +} -\#endif /* INCLUDED_AD9510_REGS_HPP */ +boost::uint32_t get_read_reg(boost::uint16_t addr){ +    return (boost::uint32_t(addr) << 8) | (1 << 23); +}  """  if __name__ == '__main__': -    regs = map(reg, parse_tmpl(REGS_DATA_TMPL).splitlines()) -    open(sys.argv[1], 'w').write(parse_tmpl(HEADER_TEXT, regs=regs, file=__file__)) +    import common; common.generate( +        name='ad9510_regs', +        regs_tmpl=REGS_TMPL, +        body_tmpl=BODY_TMPL, +        file=__file__, +    ) diff --git a/host/lib/ic_reg_maps/gen_ad9522_regs.py b/host/lib/ic_reg_maps/gen_ad9522_regs.py new file mode 100755 index 000000000..9da51205b --- /dev/null +++ b/host/lib/ic_reg_maps/gen_ad9522_regs.py @@ -0,0 +1,183 @@ +#!/usr/bin/env python +# +# 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/>. +# + +######################################################################## +# Template for raw text data describing registers +# name addr[bit range inclusive] default optional enums +######################################################################## +REGS_TMPL="""\ +sdo_active                  0x000[7]                 0           sdio, sdo_sdio +lsb_first_addr_incr         0x000[6]                 0           msb, lsb +soft_reset                  0x000[5]                 0 +mirror                      0x000[3:0]               0 +readback_active_registers   0x004[0]                 0           buffer, active +pfd_polarity                0x010[7]                 0           pos, neg +cp_current                  0x010[6:4]               7           0_6ma, 1_2ma, 1_8ma, 2_4ma, 3_0ma, 3_6ma, 4_2ma, 4_8ma +cp_mode                     0x010[3:2]               3           high_imp, force_source, force_sink, normal +pll_power_down              0x010[1:0]               1           normal=0, async=1, sync=3 +r_counter_lsb               0x011[7:0]               1 +r_counter_msb               0x012[5:0]               0 +a_counter                   0x013[5:0]               0 +b_counter_lsb               0x014[7:0]               3 +b_counter_msb               0x015[4:0]               0 +set_cp_pin_to_vcp_2         0x016[7]                 0           normal, vcp_2 +reset_r_counter             0x016[6]                 0 +reset_a_and_b_counters      0x016[5]                 0 +reset_all_counters          0x016[4]                 0 +b_counter_bypass            0x016[3]                 0           normal, div1 +prescaler_p                 0x016[2:0]               6           div1, div2, div2_3, div4_5, div8_9, div16_17, div32_33, div3 +status_pin_control          0x017[7:2]               0 +antibacklash_pulse_width    0x017[1:0]               0           2_9ns, 1_3ns, 6_0ns +enb_cmos_ref_input_dc_off   0x018[7]                 0 +lock_detect_counter         0x018[6:5]               0           5cyc, 16cyc, 64cyc, 255cyc +digital_lock_detect_window  0x018[4]                 0           high_range, low_range +disable_digital_lock_detect 0x018[3]                 0           normal, disabled +vco_calibration_divider     0x018[2:1]               3           div2, div4, div8, div16 +vco_calibration_now         0x018[0]                 0 +r_a_b_counters_sync_pin_rst 0x019[7:6]               0           nothing, async, sync +r_path_delay                0x019[5:3]               0 +n_path_delay                0x019[2:0]               0 +enable_status_pin_divider   0x01A[7]                 0 +ref_freq_monitor_threshold  0x01A[6]                 0           1_02mhz, 6khz +ld_pin_control              0x01A[5:0]               0 +enable_vco_freq_monitor     0x01B[7]                 0 +enable_ref2_freq_monitor    0x01B[6]                 0 +enable_ref1_freq_monitor    0x01B[5]                 0 +refmon_pin_control          0x01B[4:0]               0 +disable_switchover_deglitch 0x01C[7]                 0 +select_ref                  0x01C[6]                 0           ref1, ref2 +use_ref_sel_pin             0x01C[5]                 0           register, ref_sel +enb_auto_ref_switchover     0x01C[4]                 0           manual, auto +stay_on_ref2                0x01C[3]                 0           return_ref1, stay_ref2 +enable_ref2                 0x01C[2]                 0 +enable_ref1                 0x01C[1]                 0 +enable_differential_ref     0x01C[0]                 0 +enb_stat_eeprom_at_stat_pin 0x01D[7]                 1 +enable_xtal_osc             0x01D[6]                 0 +enable_clock_doubler        0x01D[5]                 0 +disable_pll_status_reg      0x01D[4]                 0 +enable_ld_pin_comparator    0x01D[3]                 0 +enable_external_holdover    0x01D[1]                 0 +enable_holdover             0x01D[0]                 0 +external_zero_delay_fcds    0x01E[4:3]               0 +enable_external_zero_delay  0x01E[2]                 0 +enable_zero_delay           0x01E[1]                 0 +######################################################################## +#for $i in range(12) +#set $addr = ($i + 0x0F0) +out$(i)_format              $(addr)[7]             0             lvds, cmos +out$(i)_cmos_configuration  $(addr)[6:5]           3             off, a_on, b_on, ab_on +out$(i)_polarity            $(addr)[4:3]           0             lvds_a_non_b_inv=0, lvds_a_inv_b_non=1, cmos_ab_non=0, cmos_ab_inv=1, cmos_a_non_b_inv=2, cmos_a_inv_b_non=3 +out$(i)_lvds_diff_voltage   $(addr)[2:1]           1             1_75ma, 3_5ma, 5_25ma, 7_0ma +out$(i)_lvds_power_down     $(addr)[0]             0 +#end for +######################################################################## +#for $i in reversed(range(8)) +csdld_en_out_$i             0x0FC[$i]                0           ignore, async +#end for +######################################################################## +#for $i in reversed(range(4)) +csdld_en_out_$(8 + $i)      0x0FD[$i]                0           ignore, async +#end for +######################################################################## +#set $default_val = 0x7 +#for $i in range(4) +#set $addr0 = hex($i*3 + 0x190) +#set $addr1 = hex($i*3 + 0x191) +#set $addr2 = hex($i*3 + 0x192) +divider$(i)_low_cycles      $(addr0)[7:4]         $default_val +divider$(i)_high_cycles     $(addr0)[3:0]         $default_val +divider$(i)_bypass          $(addr1)[7]           0 +divider$(i)_ignore_sync     $(addr1)[6]           0 +divider$(i)_force_high      $(addr1)[5]           0 +divider$(i)_start_high      $(addr1)[4]           0 +divider$(i)_phase_offset    $(addr1)[3:0]         0 +channel$(i)_power_down      $(addr2)[2]           0 +disable_divider$(i)_ddc     $(addr2)[0]           0 +#set $default_val /= 2 +#end for +######################################################################## +vco_divider                  0x1E0[2:0]              2             div2, div3, div4, div5, div6, static, div1 +power_down_clock_input_sel   0x1E1[4]                0 +power_down_vco_clock_ifc     0x1E1[3]                0 +power_down_vco_and_clock     0x1E1[2]                0 +select_vco_or_clock          0x1E1[1]                0             external, vco +bypass_vco_divider           0x1E1[0]                0 +disable_power_on_sync        0x230[3]                0 +power_down_sync              0x230[2]                0 +power_down_dist_ref          0x230[1]                0 +soft_sync                    0x230[0]                0 +io_update                    0x232[0]                0 +soft_eeprom                  0xB02[1]                0 +enable_eeprom_write          0xB02[0]                0 +reg2eeprom                   0xB03[0]                0 +""" + +######################################################################## +# Template for methods in the body of the struct +######################################################################## +BODY_TMPL="""\ +boost::uint8_t get_reg(boost::uint16_t addr){ +    boost::uint8_t reg = 0; +    switch(addr){ +    #for $addr in sorted(set(map(lambda r: r.get_addr(), $regs))) +    case $addr: +        #for $reg in filter(lambda r: r.get_addr() == addr, $regs) +        reg |= (boost::uint8_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift(); +        #end for +        break; +    #end for +    } +    if (addr == 0){ //mirror 4 bits in register 0 +        reg |= ((reg >> 7) & 0x1) << 0; +        reg |= ((reg >> 6) & 0x1) << 1; +        reg |= ((reg >> 5) & 0x1) << 2; +        reg |= ((reg >> 4) & 0x1) << 3; +    } +    return reg; +} + +void set_reg(boost::uint8_t addr, boost::uint32_t reg){ +    switch(addr){ +    #for $addr in sorted(set(map(lambda r: r.get_addr(), $regs))) +    case $addr: +        #for $reg in filter(lambda r: r.get_addr() == addr, $regs) +        $reg.get_name() = $(reg.get_type())((reg >> $reg.get_shift()) & $reg.get_mask()); +        #end for +        break; +    #end for +    } +} + +boost::uint32_t get_write_reg(boost::uint16_t addr){ +    return (boost::uint32_t(addr) << 8) | get_reg(addr); +} + +boost::uint32_t get_read_reg(boost::uint16_t addr){ +    return (boost::uint32_t(addr) << 8) | (1 << 23); +} + +""" + +if __name__ == '__main__': +    import common; common.generate( +        name='ad9522_regs', +        regs_tmpl=REGS_TMPL, +        body_tmpl=BODY_TMPL, +        file=__file__, +    ) diff --git a/host/lib/ic_reg_maps/gen_ad9777_regs.py b/host/lib/ic_reg_maps/gen_ad9777_regs.py index 2ac73efcf..abb839f0f 100755 --- a/host/lib/ic_reg_maps/gen_ad9777_regs.py +++ b/host/lib/ic_reg_maps/gen_ad9777_regs.py @@ -16,14 +16,11 @@  # along with this program.  If not, see <http://www.gnu.org/licenses/>.  # -import sys -from common import * -  ########################################################################  # Template for raw text data describing registers  # name addr[bit range inclusive] default optional enums  ######################################################################## -REGS_DATA_TMPL="""\ +REGS_TMPL="""\  ########################################################################  ## address 0  ######################################################################## @@ -73,79 +70,49 @@ qdac_fine_gain_adjust   9[0:7]   0  ## address 6 and A  ########################################################################  idac_coarse_gain_adjust 6[0:3]   0 -qdac_coarse_gain_adjust A[0:3]   0 +qdac_coarse_gain_adjust 0xA[0:3] 0  ########################################################################  ## address 7, 8 and B, C  ########################################################################  idac_offset_adjust_msb  7[0:7]   0  idac_offset_adjust_lsb  8[0:1]   0  idac_ioffset_direction  8[7]     0     out_a, out_b -qdac_offset_adjust_msb  B[0:7]   0 -qdac_offset_adjust_lsb  C[0:1]   0 -qdac_ioffset_direction  C[7]     0     out_a, out_b +qdac_offset_adjust_msb  0xB[0:7] 0 +qdac_offset_adjust_lsb  0xC[0:1] 0 +qdac_ioffset_direction  0xC[7]   0     out_a, out_b  """  ######################################################################## -# Header and Source templates below +# Template for methods in the body of the struct  ######################################################################## -HEADER_TEXT=""" -#import time - -/*********************************************************************** - * This file was generated by $file on $time.strftime("%c") - **********************************************************************/ - -\#ifndef INCLUDED_AD9777_REGS_HPP -\#define INCLUDED_AD9777_REGS_HPP - -\#include <boost/cstdint.hpp> - -struct ad9777_regs_t{ -#for $reg in $regs -    #if $reg.get_enums() -    enum $(reg.get_name())_t{ -        #for $i, $enum in enumerate($reg.get_enums()) -        #set $end_comma = ',' if $i < len($reg.get_enums())-1 else '' -        $(reg.get_name().upper())_$(enum[0].upper()) = $enum[1]$end_comma -        #end for -    } $reg.get_name(); -    #else -    boost::$reg.get_stdint_type() $reg.get_name(); -    #end if -#end for - -    ad9777_regs_t(void){ -#for $reg in $regs -        $reg.get_name() = $reg.get_default(); -#end for -    } - -    boost::uint8_t get_reg(boost::uint8_t addr){ -        boost::uint8_t reg = 0; -        switch(addr){ -        #for $addr in sorted(set(map(lambda r: r.get_addr(), $regs))) -        case $addr: -            #for $reg in filter(lambda r: r.get_addr() == addr, $regs) -            reg |= (boost::uint8_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift(); -            #end for -            break; +BODY_TMPL="""\ +boost::uint8_t get_reg(boost::uint8_t addr){ +    boost::uint8_t reg = 0; +    switch(addr){ +    #for $addr in sorted(set(map(lambda r: r.get_addr(), $regs))) +    case $addr: +        #for $reg in filter(lambda r: r.get_addr() == addr, $regs) +        reg |= (boost::uint8_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift();          #end for -        } -        return reg; +        break; +    #end for      } +    return reg; +} -    boost::uint16_t get_write_reg(boost::uint8_t addr){ -        return (boost::uint16_t(addr) << 8) | get_reg(addr); -    } - -    boost::uint16_t get_read_reg(boost::uint8_t addr){ -        return (boost::uint16_t(addr) << 8) | (1 << 7); -    } -}; +boost::uint16_t get_write_reg(boost::uint8_t addr){ +    return (boost::uint16_t(addr) << 8) | get_reg(addr); +} -\#endif /* INCLUDED_AD9777_REGS_HPP */ +boost::uint16_t get_read_reg(boost::uint8_t addr){ +    return (boost::uint16_t(addr) << 8) | (1 << 7); +}  """  if __name__ == '__main__': -    regs = map(reg, parse_tmpl(REGS_DATA_TMPL).splitlines()) -    open(sys.argv[1], 'w').write(parse_tmpl(HEADER_TEXT, regs=regs, file=__file__)) +    import common; common.generate( +        name='ad9777_regs', +        regs_tmpl=REGS_TMPL, +        body_tmpl=BODY_TMPL, +        file=__file__, +    ) diff --git a/host/lib/ic_reg_maps/gen_ad9862_regs.py b/host/lib/ic_reg_maps/gen_ad9862_regs.py new file mode 100755 index 000000000..fdbea5828 --- /dev/null +++ b/host/lib/ic_reg_maps/gen_ad9862_regs.py @@ -0,0 +1,246 @@ +#!/usr/bin/env python +# +# 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/>. +# + +######################################################################## +# Template for raw text data describing registers +# name addr[bit range inclusive] default optional enums +######################################################################## +REGS_TMPL="""\ +######################################################################## +## General +######################################################################## +sdio_bidir         0[7]              0                  sdio_sdo, sdio +lsb_first          0[6]              0                  msb, lsb +soft_reset         0[5]              0 +######################################################################## +## Rx Power Down +######################################################################## +pd_vref_diff       1[7]              0 +pd_vref            1[6]              0 +pd_rx_digital      1[5]              0 +pd_rx_channel_b    1[4]              0 +pd_rx_channel_a    1[3]              0 +pd_buffer_b        1[2]              0 +pd_buffer_a        1[1]              0 +pd_all_rx          1[0]              0 +######################################################################## +## Rx A and B +######################################################################## +#for $x, $i in (('a', 2), ('b', 3)) +byp_buffer_$x      $(i)[7]           0 +rx_pga_$x          $(i)[0:4]         0 +#end for +######################################################################## +## Rx Misc +######################################################################## +hs_duty_cycle      4[2]              0 +shared_ref         4[1]              0 +clk_duty           4[0]              0 +######################################################################## +## RX I/F (INTERFACE) +######################################################################## +three_state        5[4]              0 +rx_retime          5[3]              0       clkout1, clkout2 +rx_twos_comp       5[2]              0 +inv_rxsync         5[1]              0 +mux_out            5[0]              0       rx_mux_mode=1, dual_port_mode=0 +######################################################################## +## RX Digital +######################################################################## +two_channel        6[3]              1       rx_b_dis, both_enb +rx_keep_ve         6[2]              0       pass_pos, pass_neg +rx_hilbert         6[1]              0       dis, enb +decimate           6[0]              0       dis, enb +######################################################################## +## TX Power Down +######################################################################## +alt_timing_mode    8[5]              0 +txoff_enable       8[4]              0 +tx_digital_pd      8[3]              0 +tx_analog_pd       8[0:2]            0        none=0, txb=4, txa=2, both=7 +######################################################################## +## Tx Offset and Gain +######################################################################## +#for $x, $i, $j, $k in (('a', 10, 11, 14), ('b', 12, 13, 15)) +dac_$(x)_offset_1_0   $(i)[6:7]           0 +dac_$(x)_offset_dir   $(i)[0]             0        neg_diff, pos_dif +dac_$(x)_offset_9_2   $(j)[0:7]           0 +dac_$(x)_coarse_gain  $(k)[6:7]           0 +dac_$(x)_fine_gain    $(k)[0:5]           0 +#end for +tx_pga_gain            16[0:7]            0 +######################################################################## +## Tx Misc +######################################################################## +tx_slave_enable        17[1]              0 +tx_pga_mode            17[0]              0        normal, fast +######################################################################## +## Tx IF (INTERFACE) +######################################################################## +tx_retime              18[6]              1        clkout1=1, clkout2=0 +qi_order               18[5]              0        iq, qi +inv_txsync             18[4]              0 +tx_twos_comp           18[3]              0 +inverse_samp           18[2]              0        rise, fall +edges                  18[1]              0        normal, both +interleaved            18[0]              0        single, interleaved +######################################################################## +## TX Digital +######################################################################## +two_data_paths         19[4]              0        single, both +tx_keep_ve             19[3]              0        pass_pos, pass_neg +tx_hilbert             19[2]              0        dis, enb +interp                 19[0:1]            0        1, 2, 4 +######################################################################## +## TX Modulator +######################################################################## +neg_fine_tune          20[5]              0        pos_shift, neg_shift +fine_mode              20[4]              0        bypass, nco +real_mix_mode          20[3]              0        complex, real +neg_coarse_tune        20[2]              0        pos_shift, neg_shift +coarse_mod             20[0:1]            0        bypass, fdac_4, fdac_8 +######################################################################## +## NCO Tuning Word +######################################################################## +ftw_7_0                21[0:7]            0 +ftw_15_8               22[0:7]            0 +ftw_23_16              23[0:7]            0 +######################################################################## +## DLL +######################################################################## +input_clk_ctrl         24[6]              0       external, internal +adc_div2               24[5]              0       normal, div2 +dll_mult               24[3:4]            0       1, 2, 4 +dll_pd                 24[2]              0 +dll_mode               24[0]              0       slow, fast +######################################################################## +## Clock Out +######################################################################## +clkout2_div_factor     25[6:7]            0       1, 2, 4, 8 +inv2                   25[5]              0       normal, inverted +inv1                   25[1]              0       normal, inverted +dis2                   25[4]              0       enb, dis +dis1                   25[0]              0       enb, dis +######################################################################## +## Aux ADC +######################################################################## +#for $x, $i in (('a2', 26), ('a1', 28), ('b2', 30), ('b1', 32)) +aux_adc_$(x)_1_0       $(i)[6:7]          0 +aux_adc_$(x)_9_2       $int(1+$i)[0:7]    0 +#end for +######################################################################## +## Aux ADC Control +######################################################################## +aux_spi                34[7]              0       dis, enb +sel_bnota              34[6]              0       adc_a, adc_b +#for $x, $i in (('b', 5), ('a', 2)) +refsel_$(x)            34[$i]             0       external, internal +select_$(x)            34[$int($i-1)]     0       aux_adc2, aux_adc1 +start_$(x)             34[$int($i-2)]     0 +#end for +######################################################################## +## Aux ADC Clock +######################################################################## +clk_4                  35[0]              0       1_2, 1_4 +######################################################################## +## Aux DAC +######################################################################## +#for $x, $i in (('a', 36), ('b', 37), ('c', 38)) +aux_dac_$x             $(i)[0:7]          0 +#end for +######################################################################## +## Aux DAC Update +######################################################################## +aux_dac_slave_enable   39[7]              0 +aux_dacupdate_c        39[2]              0 +aux_dacupdate_b        39[1]              0 +aux_dacupdate_a        39[0]              0 +######################################################################## +## AUX DAC Power Down +######################################################################## +aux_dac_pd_a           40[2]              0 +aux_dac_pd_b           40[1]              0 +aux_dac_pd_c           40[0]              0 +######################################################################## +## AUX DAC Control +######################################################################## +aux_dac_invert_a       41[2]              0 +aux_dac_invert_b       41[1]              0 +aux_dac_invert_c       41[0]              0 +######################################################################## +## Sig Delt +######################################################################## +sig_delt_3_0           42[4:7]            0 +sig_delt_11_4          43[0:7]            0 +######################################################################## +## ADC Low Power +######################################################################## +rx_low_power_mode_r49 49[0:7]             0 +rx_low_power_mode_r50 50[0:7]             0 +######################################################################## +## Chip ID +######################################################################## +chip_id                63[0:7]            0 +""" + +######################################################################## +# Header and Source templates below +######################################################################## +BODY_TMPL=""" +boost::uint8_t get_reg(boost::uint8_t addr){ +    boost::uint8_t reg = 0; +    switch(addr){ +    #for $addr in range(0, 63+1) +    case $addr: +        #for $reg in filter(lambda r: r.get_addr() == addr, $regs) +        reg |= (boost::uint16_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift(); +        #end for +        break; +    #end for +    } +    return reg; +} + +void set_reg(boost::uint8_t addr, boost::uint16_t reg){ +    switch(addr){ +    #for $addr in sorted(set(map(lambda r: r.get_addr(), $regs))) +    case $addr: +        #for $reg in filter(lambda r: r.get_addr() == addr, $regs) +        $reg.get_name() = $(reg.get_type())((reg >> $reg.get_shift()) & $reg.get_mask()); +        #end for +        break; +    #end for +    } +} + +boost::uint16_t get_write_reg(boost::uint8_t addr){ +    return (boost::uint16_t(addr) << 8) | get_reg(addr); +} + +boost::uint16_t get_read_reg(boost::uint8_t addr){ +    return (boost::uint16_t(addr) << 8) | (1 << 7); +} +""" + +if __name__ == '__main__': +    import common; common.generate( +        name='ad9862_regs', +        regs_tmpl=REGS_TMPL, +        body_tmpl=BODY_TMPL, +        file=__file__, +    ) diff --git a/host/lib/ic_reg_maps/gen_adf4350_regs.py b/host/lib/ic_reg_maps/gen_adf4350_regs.py new file mode 100755 index 000000000..e97772843 --- /dev/null +++ b/host/lib/ic_reg_maps/gen_adf4350_regs.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python +# +# 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/>. +# + +######################################################################## +# Template for raw text data describing registers +# name addr[bit range inclusive] default optional enums +######################################################################## +REGS_TMPL="""\ +######################################################################## +## address 0 +######################################################################## +frac_12_bit             0[3:14]     0 +int_16_bit              0[15:30]    0x23 +##reserved              0[31]       0 +######################################################################## +## address 1 +######################################################################## +mod_12_bit              1[3:14]     0xfff +phase_12_bit            1[15:26]    0 +prescaler               1[27]       0       4_5, 8_9 +##reserved              1[28:31]    0 +######################################################################## +## address 2 +######################################################################## +counter_reset           2[3]        0       disabled, enabled +cp_three_state          2[4]        0       disabled, enabled +power_down              2[5]        0       disabled, enabled +pd_polarity             2[6]        1       negative, positive +ldp                     2[7]        0       10ns, 6ns +ldf                     2[8]        0       frac_n, int_n +#set $current_setting_enums = ', '.join(map(lambda x: '_'.join(("%0.2fma"%(round(x*31.27 + 31.27)/100)).split('.')), range(0,16))) +charge_pump_current     2[9:12]     5       $current_setting_enums +double_buffer           2[13]       0       disabled, enabled +r_counter_10_bit        2[14:23]    0 +reference_divide_by_2   2[24]       1       disabled, enabled +reference_doubler       2[25]       0       disabled, enabled +muxout                  2[26:28]    1       3state, dvdd, dgnd, rdiv, ndiv, analog_ld, dld, reserved +low_noise_and_spur      2[29:30]    3       low_noise, reserved0, reserved1, low_spur +######################################################################## +## address 3 +######################################################################## +clock_divider_12_bit    3[3:14]     0 +clock_div_mode          3[15:16]    0       clock_divider_off, fast_lock, resync_enable, reserved +##reserved              3[17]       0 +cycle_slip_reduction    3[18]       0       disabled, enabled +##reserved              3[19:20]    0 +##reserved              3[21:31]    0 +######################################################################## +## address 4 +######################################################################## +output_power            4[3:4]      3       m4dbm, m1dbm, 2dbm, 5dbm +rf_output_enable        4[5]        1       disabled, enabled +aux_output_power        4[6:7]      0       m4dbm, m1dbm, 2dbm, 5dbm +aux_output_enable       4[8]        0       disabled, enabled +aux_output_select       4[9]        1       divided, fundamental +mute_till_lock_detect   4[10]       0       mute_disabled, mute_enabled +vco_power_down          4[11]       0       vco_powered_up, vco_powered_down +band_select_clock_div   4[12:19]    0 +rf_divider_select       4[20:22]    0       div1, div2, div4, div8, div16 +feedback_select         4[23]       1       divided, fundamental +##reserved              4[24:31]    0 +######################################################################## +## address 5 +######################################################################## +##reserved              5[3:18]     0 +##reserved              5[19:20]    0 +##reserved              5[21]       0 +ld_pin_mode             5[22:23]    1       low0, dld, low, high +##reserved              5[24:31]    0 +""" + +######################################################################## +# Template for methods in the body of the struct +######################################################################## +BODY_TMPL="""\ +enum addr_t{ +    ADDR_R0 = 0, +    ADDR_R1 = 1, +    ADDR_R2 = 2, +    ADDR_R3 = 3, +    ADDR_R4 = 4, +    ADDR_R5 = 5 +}; + +boost::uint32_t get_reg(boost::uint8_t addr){ +    boost::uint32_t reg = addr & 0x7; +    switch(addr){ +    #for $addr in range(5+1) +    case $addr: +        #for $reg in filter(lambda r: r.get_addr() == addr, $regs) +        reg |= (boost::uint32_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift(); +        #end for +        break; +    #end for +    } +    return reg; +} +""" + +if __name__ == '__main__': +    import common; common.generate( +        name='adf4350_regs', +        regs_tmpl=REGS_TMPL, +        body_tmpl=BODY_TMPL, +        file=__file__, +    ) diff --git a/host/lib/ic_reg_maps/gen_adf4360_regs.py b/host/lib/ic_reg_maps/gen_adf4360_regs.py index 478e471a3..3fd8707a7 100755 --- a/host/lib/ic_reg_maps/gen_adf4360_regs.py +++ b/host/lib/ic_reg_maps/gen_adf4360_regs.py @@ -16,14 +16,11 @@  # along with this program.  If not, see <http://www.gnu.org/licenses/>.  # -import sys -from common import * -  ########################################################################  # Template for raw text data describing registers  # name addr[bit range inclusive] default optional enums  ######################################################################## -REGS_DATA_TMPL="""\ +REGS_TMPL="""\  ########################################################################  ## address 0  ######################################################################## @@ -59,64 +56,34 @@ band_select_clock_div    1[20:21]   0           1, 2, 4, 8  """  ######################################################################## -# Header and Source templates below +# Template for methods in the body of the struct  ######################################################################## -HEADER_TEXT=""" -#import time - -/*********************************************************************** - * This file was generated by $file on $time.strftime("%c") - **********************************************************************/ - -\#ifndef INCLUDED_ADF4360_REGS_HPP -\#define INCLUDED_ADF4360_REGS_HPP - -\#include <boost/cstdint.hpp> - -struct adf4360_regs_t{ -#for $reg in $regs -    #if $reg.get_enums() -    enum $(reg.get_name())_t{ -        #for $i, $enum in enumerate($reg.get_enums()) -        #set $end_comma = ',' if $i < len($reg.get_enums())-1 else '' -        $(reg.get_name().upper())_$(enum[0].upper()) = $enum[1]$end_comma -        #end for -    } $reg.get_name(); -    #else -    boost::$reg.get_stdint_type() $reg.get_name(); -    #end if -#end for - -    adf4360_regs_t(void){ -#for $reg in $regs -        $reg.get_name() = $reg.get_default(); -#end for -    } - -    enum addr_t{ -        ADDR_CONTROL = 0, -        ADDR_NCOUNTER = 2, -        ADDR_RCOUNTER = 1 -    }; +BODY_TMPL="""\ +enum addr_t{ +    ADDR_CONTROL = 0, +    ADDR_NCOUNTER = 2, +    ADDR_RCOUNTER = 1 +}; -    boost::uint32_t get_reg(addr_t addr){ -        boost::uint32_t reg = addr & 0x3; -        switch(addr){ -        #for $addr in (0, 1, 2) -        case $addr: -            #for $reg in filter(lambda r: r.get_addr() == addr, $regs) -            reg |= (boost::uint32_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift(); -            #end for -            break; +boost::uint32_t get_reg(addr_t addr){ +    boost::uint32_t reg = addr & 0x3; +    switch(addr){ +    #for $addr in sorted(set(map(lambda r: r.get_addr(), $regs))) +    case $addr: +        #for $reg in filter(lambda r: r.get_addr() == addr, $regs) +        reg |= (boost::uint32_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift();          #end for -        } -        return reg; +        break; +    #end for      } -}; - -\#endif /* INCLUDED_ADF4360_REGS_HPP */ +    return reg; +}  """  if __name__ == '__main__': -    regs = map(reg, parse_tmpl(REGS_DATA_TMPL).splitlines()) -    open(sys.argv[1], 'w').write(parse_tmpl(HEADER_TEXT, regs=regs, file=__file__)) +    import common; common.generate( +        name='adf4360_regs', +        regs_tmpl=REGS_TMPL, +        body_tmpl=BODY_TMPL, +        file=__file__, +    ) diff --git a/host/lib/ic_reg_maps/gen_max2829_regs.py b/host/lib/ic_reg_maps/gen_max2829_regs.py index 7fef302a8..383131c18 100755 --- a/host/lib/ic_reg_maps/gen_max2829_regs.py +++ b/host/lib/ic_reg_maps/gen_max2829_regs.py @@ -16,14 +16,11 @@  # along with this program.  If not, see <http://www.gnu.org/licenses/>.  # -import sys -from common import * -  ########################################################################  # Template for raw text data describing registers  # name addr[bit range inclusive] default optional enums  ######################################################################## -REGS_DATA_TMPL="""\ +REGS_TMPL="""\  ########################################################################  ## Note: offsets given from perspective of data bits (excludes address)  ######################################################################## @@ -41,7 +38,7 @@ mimo_select           2[13]         0                 normal, mimo  ########################################################################  ## Integer Divider Ratio (3)  ######################################################################## -int_div_ratio_word    3[0:7]        a2 +int_div_ratio_word    3[0:7]        0xa2  frac_div_ratio_lsb    3[12:13]      0  ########################################################################  ## Fractional Divider Ratio (4) @@ -95,72 +92,42 @@ tx_vga_gain_spi       9[10]         0                 io, spi  ########################################################################  ## PA Bias DAC (10)  ######################################################################## -pa_bias_dac_out_curr  a[0:5]        0 -pa_bias_dac_delay     a[6:9]        f +pa_bias_dac_out_curr  10[0:5]       0 +pa_bias_dac_delay     10[6:9]       0xf  ########################################################################  ## Rx Gain (11)  ######################################################################## -rx_vga_gain           b[0:4]        1f -rx_lna_gain           b[5:6]        3 +rx_vga_gain           11[0:4]       0x1f +rx_lna_gain           11[5:6]       3  ########################################################################  ## Tx VGA Gain (12)  ######################################################################## -tx_vga_gain           c[0:5]        0 +tx_vga_gain           12[0:5]       0  """  ######################################################################## -# Header and Source templates below +# Template for methods in the body of the struct  ######################################################################## -HEADER_TEXT=""" -#import time - -/*********************************************************************** - * This file was generated by $file on $time.strftime("%c") - **********************************************************************/ - -\#ifndef INCLUDED_MAX2829_REGS_HPP -\#define INCLUDED_MAX2829_REGS_HPP - -\#include <boost/cstdint.hpp> - -struct max2829_regs_t{ -#for $reg in $regs -    #if $reg.get_enums() -    enum $(reg.get_name())_t{ -        #for $i, $enum in enumerate($reg.get_enums()) -        #set $end_comma = ',' if $i < len($reg.get_enums())-1 else '' -        $(reg.get_name().upper())_$(enum[0].upper()) = $enum[1]$end_comma +BODY_TMPL="""\ +boost::uint32_t get_reg(boost::uint8_t addr){ +    boost::uint16_t reg = 0; +    switch(addr){ +    #for $addr in sorted(set(map(lambda r: r.get_addr(), $regs))) +    case $addr: +        #for $reg in filter(lambda r: r.get_addr() == addr, $regs) +        reg |= (boost::uint16_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift();          #end for -    } $reg.get_name(); -    #else -    boost::$reg.get_stdint_type() $reg.get_name(); -    #end if -#end for - -    max2829_regs_t(void){ -#for $reg in $regs -        $reg.get_name() = $reg.get_default(); -#end for +        break; +    #end for      } - -    boost::uint32_t get_reg(boost::uint8_t addr){ -        boost::uint16_t reg = 0; -        switch(addr){ -        #for $addr in range(2, 12+1) -        case $addr: -            #for $reg in filter(lambda r: r.get_addr() == addr, $regs) -            reg |= (boost::uint16_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift(); -            #end for -            break; -        #end for -        } -        return (boost::uint32_t(reg) << 4) | (addr & 0xf); -    } -}; - -\#endif /* INCLUDED_MAX2829_REGS_HPP */ +    return (boost::uint32_t(reg) << 4) | (addr & 0xf); +}  """  if __name__ == '__main__': -    regs = map(reg, parse_tmpl(REGS_DATA_TMPL).splitlines()) -    open(sys.argv[1], 'w').write(parse_tmpl(HEADER_TEXT, regs=regs, file=__file__)) +    import common; common.generate( +        name='max2829_regs', +        regs_tmpl=REGS_TMPL, +        body_tmpl=BODY_TMPL, +        file=__file__, +    ) diff --git a/host/lib/load_modules.cpp b/host/lib/load_modules.cpp index ef633325d..d6bfe1369 100644 --- a/host/lib/load_modules.cpp +++ b/host/lib/load_modules.cpp @@ -20,10 +20,11 @@  #include <boost/foreach.hpp>  #include <boost/algorithm/string.hpp>  #include <boost/filesystem.hpp> +#include <boost/program_options.hpp>  #include <iostream>  #include <stdexcept> -#include <cstdlib> +namespace po = boost::program_options;  namespace fs = boost::filesystem;  /*********************************************************************** @@ -100,14 +101,39 @@ static void load_path(const fs::path &path){      }  } +//! The string constant for the module path environment variable +static const std::string MODULE_PATH_KEY = "UHD_MODULE_PATH"; + +/*! + * Name mapper function for the environment variable parser. + * Map environment variable names (that we use) to option names. + * \param the variable name + * \return the option name or blank string + */ +static std::string name_mapper(const std::string &var_name){ +    if (var_name == MODULE_PATH_KEY) return var_name; +    return ""; +} +  /*!   * Load all the modules given by the module path enviroment variable.   * The path variable may be several paths split by path separators.   */  UHD_STATIC_BLOCK(load_modules){ -    //get the environment variable module path -    char *env_module_path = std::getenv("UHD_MODULE_PATH"); -    if (env_module_path == NULL) return; +    //register the options +    std::string env_module_path; +    po::options_description desc("UHD Module Options"); +    desc.add_options() +        (MODULE_PATH_KEY.c_str(), po::value<std::string>(&env_module_path)->default_value("")) +    ; + +    //parse environment variables +    po::variables_map vm; +    po::store(po::parse_environment(desc, &name_mapper), vm); +    po::notify(vm); + +    if (env_module_path == "") return; +    //std::cout << "env_module_path: " << env_module_path << std::endl;      //split the path at the path separators      std::vector<std::string> module_paths; diff --git a/host/lib/transport/CMakeLists.txt b/host/lib/transport/CMakeLists.txt new file mode 100644 index 000000000..a36f0fc03 --- /dev/null +++ b/host/lib/transport/CMakeLists.txt @@ -0,0 +1,52 @@ +# +# 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/>. +# + +#This file will be included by cmake, use absolute paths! + +######################################################################## +# Setup defines for interface address discovery +######################################################################## +MESSAGE(STATUS "Configuring interface address discovery...") + +INCLUDE(CheckIncludeFileCXX) +CHECK_INCLUDE_FILE_CXX(ifaddrs.h HAVE_IFADDRS_H) +CHECK_INCLUDE_FILE_CXX(winsock2.h HAVE_WINSOCK2_H) + +IF(HAVE_IFADDRS_H) +    MESSAGE(STATUS "  Interface address discovery supported through getifaddrs.") +    ADD_DEFINITIONS(-DHAVE_IFADDRS_H) +ELSEIF(HAVE_WINSOCK2_H) +    MESSAGE(STATUS "  Interface address discovery supported through SIO_GET_INTERFACE_LIST.") +    ADD_DEFINITIONS(-DHAVE_WINSOCK2_H) +ELSE(HAVE_IFADDRS_H) +    MESSAGE(STATUS "  Interface address discovery not supported.") +ENDIF(HAVE_IFADDRS_H) + +######################################################################## +# Append to the list of sources for lib uhd +######################################################################## +LIBUHD_PYTHON_GEN_SOURCE( +    ${CMAKE_SOURCE_DIR}/lib/transport/gen_vrt.py +    ${CMAKE_BINARY_DIR}/lib/transport/vrt.cpp +) + +LIBUHD_APPEND_SOURCES( +    ${CMAKE_SOURCE_DIR}/lib/transport/convert_types.cpp +    ${CMAKE_SOURCE_DIR}/lib/transport/if_addrs.cpp +    ${CMAKE_SOURCE_DIR}/lib/transport/udp_simple.cpp +    ${CMAKE_SOURCE_DIR}/lib/transport/udp_zero_copy_asio.cpp +) diff --git a/host/lib/transport/gen_vrt.py b/host/lib/transport/gen_vrt.py index 38a394dee..9a57c83c3 100755 --- a/host/lib/transport/gen_vrt.py +++ b/host/lib/transport/gen_vrt.py @@ -200,15 +200,11 @@ void vrt::unpack(  }  """ -import os  import sys  from Cheetah.Template import Template  def parse_tmpl(_tmpl_text, **kwargs):      return str(Template(_tmpl_text, kwargs)) -def safe_makedirs(path): -    not os.path.isdir(path) and os.makedirs(path)  if __name__ == '__main__': -    safe_makedirs(os.path.dirname(sys.argv[1]))      open(sys.argv[1], 'w').write(parse_tmpl(TMPL_TEXT, file=__file__)) diff --git a/host/lib/transport/udp_zero_copy_asio.cpp b/host/lib/transport/udp_zero_copy_asio.cpp index 09386a60c..ee44803f4 100644 --- a/host/lib/transport/udp_zero_copy_asio.cpp +++ b/host/lib/transport/udp_zero_copy_asio.cpp @@ -19,6 +19,8 @@  #include <boost/cstdint.hpp>  #include <boost/asio.hpp>  #include <boost/thread.hpp> +#include <boost/format.hpp> +#include <iostream>  using namespace uhd::transport; @@ -103,8 +105,18 @@ public:      managed_send_buffer::sptr get_send_buff(void);      //resize -    size_t resize_recv_buff_size(size_t num_bytes); -    size_t resize_send_buff_size(size_t num_bytes); +    size_t resize_recv_buff(size_t num_bytes){ +        boost::asio::socket_base::receive_buffer_size option(num_bytes); +        _socket->set_option(option); +        _socket->get_option(option); +        return option.value(); +    } +    size_t resize_send_buff(size_t num_bytes){ +        boost::asio::socket_base::send_buffer_size option(num_bytes); +        _socket->set_option(option); +        _socket->get_option(option); +        return option.value(); +    }  private:      boost::asio::ip::udp::socket   *_socket; @@ -157,25 +169,34 @@ managed_send_buffer::sptr udp_zero_copy_impl::get_send_buff(void){      );  } -size_t udp_zero_copy_impl::resize_recv_buff_size(size_t num_bytes){ -    boost::asio::socket_base::receive_buffer_size option(num_bytes); -    _socket->set_option(option); -    _socket->get_option(option); -    return option.value(); -} - -size_t udp_zero_copy_impl::resize_send_buff_size(size_t num_bytes){ -    boost::asio::socket_base::send_buffer_size option(num_bytes); -    _socket->set_option(option); -    _socket->get_option(option); -    return option.value(); -} -  /***********************************************************************   * UDP zero copy make function   **********************************************************************/  udp_zero_copy::sptr udp_zero_copy::make( -    const std::string &addr, const std::string &port +    const std::string &addr, +    const std::string &port, +    size_t recv_buff_size, +    size_t send_buff_size  ){ -    return sptr(new udp_zero_copy_impl(addr, port)); +    boost::shared_ptr<udp_zero_copy_impl> udp_trans(new udp_zero_copy_impl(addr, port)); + +    //resize the recv buffer if size was provided +    if (recv_buff_size > 0){ +        size_t actual_bytes = udp_trans->resize_recv_buff(recv_buff_size); +        if (recv_buff_size != actual_bytes) std::cout << boost::format( +            "Target recv buffer size: %d\n" +            "Actual recv byffer size: %d" +        ) % recv_buff_size % actual_bytes << std::endl; +    } + +    //resize the send buffer if size was provided +    if (send_buff_size > 0){ +        size_t actual_bytes = udp_trans->resize_send_buff(send_buff_size); +        if (send_buff_size != actual_bytes) std::cout << boost::format( +            "Target send buffer size: %d\n" +            "Actual send byffer size: %d" +        ) % send_buff_size % actual_bytes << std::endl; +    } + +    return udp_trans;  } diff --git a/host/lib/types.cpp b/host/lib/types.cpp index 14f7651d4..ec9c8ac01 100644 --- a/host/lib/types.cpp +++ b/host/lib/types.cpp @@ -143,7 +143,7 @@ device_addr_t::device_addr_t(const std::string &args){      }  } -std::string device_addr_t::to_string(void) const{ +std::string device_addr_t::to_pp_string(void) const{      if (this->size() == 0) return "Empty Device Address";      std::stringstream ss; @@ -153,7 +153,7 @@ std::string device_addr_t::to_string(void) const{      return ss.str();  } -std::string device_addr_t::to_args_str(void) const{ +std::string device_addr_t::to_string(void) const{      std::string args_str;      BOOST_FOREACH(const std::string &key, this->keys()){          args_str += key + pair_delim + (*this)[key] + arg_delim; diff --git a/host/lib/usrp/CMakeLists.txt b/host/lib/usrp/CMakeLists.txt new file mode 100644 index 000000000..39a72ab37 --- /dev/null +++ b/host/lib/usrp/CMakeLists.txt @@ -0,0 +1,27 @@ +# +# 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/>. +# + +#This file will be included by cmake, use absolute paths! + +LIBUHD_APPEND_SOURCES( +    ${CMAKE_SOURCE_DIR}/lib/usrp/dboard_base.cpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/dboard_eeprom.cpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/dboard_id.cpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/dboard_manager.cpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/simple_usrp.cpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/tune_helper.cpp +) diff --git a/host/lib/usrp/dboard/CMakeLists.txt b/host/lib/usrp/dboard/CMakeLists.txt new file mode 100644 index 000000000..3a6c2d84a --- /dev/null +++ b/host/lib/usrp/dboard/CMakeLists.txt @@ -0,0 +1,26 @@ +# +# 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/>. +# + +#This file will be included by cmake, use absolute paths! + +LIBUHD_APPEND_SOURCES( +    ${CMAKE_SOURCE_DIR}/lib/usrp/dboard/db_basic_and_lf.cpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/dboard/db_rfx.cpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/dboard/db_xcvr2450.cpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/dboard/db_wbx.cpp +) + diff --git a/host/lib/usrp/dboard/db_basic_and_lf.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp index b0fbbd2ec..23ac98872 100644 --- a/host/lib/usrp/dboard/db_basic_and_lf.cpp +++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp @@ -34,7 +34,7 @@ using namespace boost::assign;   **********************************************************************/  class basic_rx : public rx_dboard_base{  public: -    basic_rx(ctor_args_t const& args, double max_freq); +    basic_rx(ctor_args_t args, double max_freq);      ~basic_rx(void);      void rx_get(const wax::obj &key, wax::obj &val); @@ -46,7 +46,7 @@ private:  class basic_tx : public tx_dboard_base{  public: -    basic_tx(ctor_args_t const& args, double max_freq); +    basic_tx(ctor_args_t args, double max_freq);      ~basic_tx(void);      void tx_get(const wax::obj &key, wax::obj &val); @@ -59,19 +59,19 @@ private:  /***********************************************************************   * Register the basic and LF dboards   **********************************************************************/ -static dboard_base::sptr make_basic_rx(dboard_base::ctor_args_t const& args){ +static dboard_base::sptr make_basic_rx(dboard_base::ctor_args_t args){      return dboard_base::sptr(new basic_rx(args, 90e9));  } -static dboard_base::sptr make_basic_tx(dboard_base::ctor_args_t const& args){ +static dboard_base::sptr make_basic_tx(dboard_base::ctor_args_t args){      return dboard_base::sptr(new basic_tx(args, 90e9));  } -static dboard_base::sptr make_lf_rx(dboard_base::ctor_args_t const& args){ +static dboard_base::sptr make_lf_rx(dboard_base::ctor_args_t args){      return dboard_base::sptr(new basic_rx(args, 32e6));  } -static dboard_base::sptr make_lf_tx(dboard_base::ctor_args_t const& args){ +static dboard_base::sptr make_lf_tx(dboard_base::ctor_args_t args){      return dboard_base::sptr(new basic_tx(args, 32e6));  } @@ -85,7 +85,7 @@ UHD_STATIC_BLOCK(reg_basic_and_lf_dboards){  /***********************************************************************   * Basic and LF RX dboard   **********************************************************************/ -basic_rx::basic_rx(ctor_args_t const& args, double max_freq) : rx_dboard_base(args){ +basic_rx::basic_rx(ctor_args_t args, double max_freq) : rx_dboard_base(args){      _max_freq = max_freq;  } @@ -101,7 +101,7 @@ void basic_rx::rx_get(const wax::obj &key_, wax::obj &val){      switch(key.as<subdev_prop_t>()){      case SUBDEV_PROP_NAME:          val = std::string(str(boost::format("%s - %s") -            % dboard_id::to_string(get_rx_id()) +            % get_rx_id().to_pp_string()              % get_subdev_name()          ));          return; @@ -187,7 +187,7 @@ void basic_rx::rx_set(const wax::obj &key_, const wax::obj &val){  /***********************************************************************   * Basic and LF TX dboard   **********************************************************************/ -basic_tx::basic_tx(ctor_args_t const& args, double max_freq) : tx_dboard_base(args){ +basic_tx::basic_tx(ctor_args_t args, double max_freq) : tx_dboard_base(args){      _max_freq = max_freq;  } @@ -202,7 +202,7 @@ void basic_tx::tx_get(const wax::obj &key_, wax::obj &val){      //handle the get request conditioned on the key      switch(key.as<subdev_prop_t>()){      case SUBDEV_PROP_NAME: -        val = dboard_id::to_string(get_tx_id()); +        val = get_tx_id().to_pp_string();          return;      case SUBDEV_PROP_OTHERS: diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index 175f55eab..bbc9716b1 100644 --- a/host/lib/usrp/dboard/db_rfx.cpp +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -63,7 +63,7 @@ static const float _max_rx_pga0_gain = 45;  class rfx_xcvr : public xcvr_dboard_base{  public:      rfx_xcvr( -        ctor_args_t const& args, +        ctor_args_t args,          const freq_range_t &freq_range,          bool rx_div2, bool tx_div2      ); @@ -108,23 +108,23 @@ private:  /***********************************************************************   * Register the RFX dboards (min freq, max freq, rx div2, tx div2)   **********************************************************************/ -static dboard_base::sptr make_rfx_flex400(dboard_base::ctor_args_t const& args){ +static dboard_base::sptr make_rfx_flex400(dboard_base::ctor_args_t args){      return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(400e6, 500e6), false, true));  } -static dboard_base::sptr make_rfx_flex900(dboard_base::ctor_args_t const& args){ +static dboard_base::sptr make_rfx_flex900(dboard_base::ctor_args_t args){      return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(750e6, 1050e6), true, true));  } -static dboard_base::sptr make_rfx_flex1800(dboard_base::ctor_args_t const& args){ +static dboard_base::sptr make_rfx_flex1800(dboard_base::ctor_args_t args){      return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(1500e6, 2100e6), false, false));  } -static dboard_base::sptr make_rfx_flex1200(dboard_base::ctor_args_t const& args){ +static dboard_base::sptr make_rfx_flex1200(dboard_base::ctor_args_t args){      return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(1150e6, 1450e6), true, true));  } -static dboard_base::sptr make_rfx_flex2400(dboard_base::ctor_args_t const& args){ +static dboard_base::sptr make_rfx_flex2400(dboard_base::ctor_args_t args){      return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(2300e6, 2900e6), false, false));  } @@ -149,7 +149,7 @@ UHD_STATIC_BLOCK(reg_rfx_dboards){   * Structors   **********************************************************************/  rfx_xcvr::rfx_xcvr( -    ctor_args_t const& args, +    ctor_args_t args,      const freq_range_t &freq_range,      bool rx_div2, bool tx_div2  ) : xcvr_dboard_base(args){ @@ -351,7 +351,7 @@ void rfx_xcvr::rx_get(const wax::obj &key_, wax::obj &val){      //handle the get request conditioned on the key      switch(key.as<subdev_prop_t>()){      case SUBDEV_PROP_NAME: -        val = dboard_id::to_string(get_rx_id()); +        val = get_rx_id().to_pp_string();          return;      case SUBDEV_PROP_OTHERS: @@ -448,7 +448,7 @@ void rfx_xcvr::tx_get(const wax::obj &key_, wax::obj &val){      //handle the get request conditioned on the key      switch(key.as<subdev_prop_t>()){      case SUBDEV_PROP_NAME: -        val = dboard_id::to_string(get_tx_id()); +        val = get_tx_id().to_pp_string();          return;      case SUBDEV_PROP_OTHERS: diff --git a/host/lib/usrp/dboard/db_wbx.cpp b/host/lib/usrp/dboard/db_wbx.cpp new file mode 100644 index 000000000..2a8a3a9f2 --- /dev/null +++ b/host/lib/usrp/dboard/db_wbx.cpp @@ -0,0 +1,613 @@ +// +// 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/>. +// + +static const bool wbx_debug = false; + +// Common IO Pins +#define ANTSW_IO        ((1 << 5)|(1 << 15))    // on UNIT_TX, 0 = TX, 1 = RX, on UNIT_RX 0 = main ant, 1 = RX2 +#define ADF4350_CE      (1 << 3) +#define ADF4350_PDBRF   (1 << 2) +#define ADF4350_MUXOUT  (1 << 1)                // INPUT!!! +#define LOCKDET_MASK    (1 << 0)                // INPUT!!! + +// TX IO Pins +#define TX_PUP_5V       (1 << 7)                // enables 5.0V power supply +#define TX_PUP_3V       (1 << 6)                // enables 3.3V supply +#define TXMOD_EN        (1 << 4)                // on UNIT_TX, 1 enables TX Modulator + +// RX IO Pins +#define RX_PUP_5V       (1 << 7)                // enables 5.0V power supply +#define RX_PUP_3V       (1 << 6)                // enables 3.3V supply +#define RXBB_PDB        (1 << 4)                // on UNIT_RX, 1 powers up RX baseband + +// RX Attenuator Pins +#define RX_ATTN_SHIFT   8                       // lsb of RX Attenuator Control +#define RX_ATTN_MASK    (63 << RX_ATTN_SHIFT)      // valid bits of RX Attenuator Control + +// Mixer functions +#define TX_MIXER_ENB    (TXMOD_EN|ADF4350_PDBRF) +#define TX_MIXER_DIS    0 + +#define RX_MIXER_ENB    (RXBB_PDB|ADF4350_PDBRF) +#define RX_MIXER_DIS    0 + +// Pin functions +#define TX_POWER_IO     (TX_PUP_5V|TX_PUP_3V)   // high enables power supply +#define TXIO_MASK       (TX_POWER_IO|ANTSW_IO|ADF4350_CE|ADF4350_PDBRF|TXMOD_EN) + +#define RX_POWER_IO     (RX_PUP_5V|RX_PUP_3V)   // high enables power supply +#define RXIO_MASK       (RX_POWER_IO|ANTSW_IO|ADF4350_CE|ADF4350_PDBRF|RXBB_PDB|RX_ATTN_MASK) + +// Power functions +#define TX_POWER_UP     (TX_POWER_IO|ADF4350_CE) +#define TX_POWER_DOWN   0 + +#define RX_POWER_UP     (RX_POWER_IO|ADF4350_CE) +#define RX_POWER_DOWN   0 + +// Antenna constants +#define ANT_TX          0                       //the tx line is transmitting +#define ANT_RX          ANTSW_IO                //the tx line is receiving +#define ANT_TXRX        0                       //the rx line is on txrx +#define ANT_RX2         ANTSW_IO                //the rx line in on rx2 +#define ANT_XX          0                       //dont care how the antenna is set + +#include "adf4350_regs.hpp" +#include <uhd/types/dict.hpp> +#include <uhd/usrp/subdev_props.hpp> +#include <uhd/types/ranges.hpp> +#include <uhd/utils/assert.hpp> +#include <uhd/utils/static.hpp> +#include <uhd/utils/algorithm.hpp> +#include <uhd/usrp/dboard_base.hpp> +#include <uhd/usrp/dboard_manager.hpp> +#include <boost/assign/list_of.hpp> +#include <boost/format.hpp> +#include <boost/math/special_functions/round.hpp> + +using namespace uhd; +using namespace uhd::usrp; +using namespace boost::assign; + +/*********************************************************************** + * The WBX dboard + **********************************************************************/ +static const float _max_rx_pga0_gain = 31.5; +static const float _max_tx_pga0_gain = 25; + +class wbx_xcvr : public xcvr_dboard_base{ +public: +    wbx_xcvr( +        ctor_args_t args, +        const freq_range_t &freq_range +    ); +    ~wbx_xcvr(void); + +    void rx_get(const wax::obj &key, wax::obj &val); +    void rx_set(const wax::obj &key, const wax::obj &val); + +    void tx_get(const wax::obj &key, wax::obj &val); +    void tx_set(const wax::obj &key, const wax::obj &val); + +private: +    freq_range_t _freq_range; +    uhd::dict<dboard_iface::unit_t, bool> _div2; +    double       _rx_lo_freq, _tx_lo_freq; +    std::string  _rx_ant; +    int          _rx_pga0_attn_iobits; +    float        _rx_pga0_gain; +    float        _tx_pga0_gain; + +    void set_rx_lo_freq(double freq); +    void set_tx_lo_freq(double freq); +    void set_rx_ant(const std::string &ant); +    void set_rx_pga0_gain(float gain); +    void set_rx_pga0_attn(float attn); +    void set_tx_pga0_gain(float gain); + +    void update_atr(void); + +    /*! +     * Set the LO frequency for the particular dboard unit. +     * \param unit which unit rx or tx +     * \param target_freq the desired frequency in Hz +     * \return the actual frequency in Hz +     */ +    double set_lo_freq(dboard_iface::unit_t unit, double target_freq); + +    /*! +     * Get the lock detect status of the LO. +     * \param unit which unit rx or tx +     * \return true for locked +     */ +    bool get_locked(dboard_iface::unit_t unit){ +        return (this->get_iface()->read_gpio(unit) & LOCKDET_MASK) != 0; +    } +}; + +/*********************************************************************** + * Register the WBX dboard (min freq, max freq, rx div2, tx div2) + **********************************************************************/ +static dboard_base::sptr make_wbx(dboard_base::ctor_args_t args){ +    return dboard_base::sptr(new wbx_xcvr(args, freq_range_t(50e6, 2220e6))); +} + +UHD_STATIC_BLOCK(reg_wbx_dboards){ +    dboard_manager::register_dboard(0x0052, &make_wbx, "WBX RX"); +    dboard_manager::register_dboard(0x0053, &make_wbx, "WBX TX"); +} + +/*********************************************************************** + * Structors + **********************************************************************/ +wbx_xcvr::wbx_xcvr( +    ctor_args_t args, +    const freq_range_t &freq_range +) : xcvr_dboard_base(args){ +    _freq_range = freq_range; + +    //enable the clocks that we need +    this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true); +    this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true); + +    //set the gpio directions +    this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_TX, TXIO_MASK); +    this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, RXIO_MASK); +    if (wbx_debug) std::cerr << boost::format( +        "WBX GPIO Direction: RX: 0x%08x, TX: 0x%08x" +    ) % RXIO_MASK % TXIO_MASK << std::endl; + +    //set some default values +    set_rx_lo_freq((_freq_range.min + _freq_range.max)/2.0); +    set_tx_lo_freq((_freq_range.min + _freq_range.max)/2.0); +    set_rx_ant("RX2"); +    set_rx_pga0_gain(0); +    set_tx_pga0_gain(0); +} + +wbx_xcvr::~wbx_xcvr(void){ +    /* NOP */ +} + +/*********************************************************************** + * Helper Methods + **********************************************************************/ +void wbx_xcvr::update_atr(void){ +    //calculate atr pins + +    //setup the tx atr (this does not change with antenna) +    this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_IDLE,        TX_POWER_UP | ANT_XX | TX_MIXER_DIS); +    this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_RX_ONLY,     TX_POWER_UP | ANT_RX | TX_MIXER_DIS); +    this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_TX_ONLY,     TX_POWER_UP | ANT_TX | TX_MIXER_ENB); +    this->get_iface()->set_atr_reg(dboard_iface::UNIT_TX, dboard_iface::ATR_REG_FULL_DUPLEX, TX_POWER_UP | ANT_TX | TX_MIXER_ENB); + +    //setup the rx atr (this does not change with antenna) +    this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_IDLE, +        _rx_pga0_attn_iobits | RX_POWER_UP | ANT_XX | RX_MIXER_DIS); +    this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_TX_ONLY, +        _rx_pga0_attn_iobits | RX_POWER_UP | ANT_XX | RX_MIXER_DIS); +    this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, +        _rx_pga0_attn_iobits | RX_POWER_UP | ANT_RX2| RX_MIXER_ENB); + +    //set the rx atr regs that change with antenna setting +    this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_RX_ONLY, +        _rx_pga0_attn_iobits | RX_POWER_UP | RX_MIXER_ENB | ((_rx_ant == "TX/RX")? ANT_TXRX : ANT_RX2)); +    if (wbx_debug) std::cerr << boost::format( +        "WBX RXONLY ATR REG: 0x%08x" +    ) % (_rx_pga0_attn_iobits | RX_POWER_UP | RX_MIXER_ENB | ((_rx_ant == "TX/RX")? ANT_TXRX : ANT_RX2)) << std::endl; +} + +void wbx_xcvr::set_rx_lo_freq(double freq){ +    _rx_lo_freq = set_lo_freq(dboard_iface::UNIT_RX, freq); +} + +void wbx_xcvr::set_tx_lo_freq(double freq){ +    _tx_lo_freq = set_lo_freq(dboard_iface::UNIT_TX, freq); +} + +void wbx_xcvr::set_rx_ant(const std::string &ant){ +    //validate input +    UHD_ASSERT_THROW(ant == "TX/RX" or ant == "RX2"); + +    //shadow the setting +    _rx_ant = ant; + +    //write the new antenna setting to atr regs +    update_atr(); +} + +void wbx_xcvr::set_rx_pga0_gain(float gain){ +    //clip the input +    gain = std::clip<float>(gain, 0, _max_rx_pga0_gain); + +    //shadow the setting (does not account for precision loss) +    _rx_pga0_gain = gain; + +    //convert to attenuation and update iobits for atr +    set_rx_pga0_attn(_max_rx_pga0_gain - gain); + +    //write the new gain to atr regs +    update_atr(); +} + +void wbx_xcvr::set_rx_pga0_attn(float attn) +{ +    int attn_code = int(floor(attn*2)); +    _rx_pga0_attn_iobits = ((~attn_code) << RX_ATTN_SHIFT) & RX_ATTN_MASK; +    if (wbx_debug) std::cerr << boost::format( +        "WBX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x" +    ) % attn % attn_code % (_rx_pga0_attn_iobits & RX_ATTN_MASK) % RX_ATTN_MASK << std::endl; +} + +void wbx_xcvr::set_tx_pga0_gain(float gain){ +    //clip the input +    gain = std::clip<float>(gain, 0, _max_tx_pga0_gain); + +    //voltage level constants +    static const float max_volts = float(0.5), min_volts = float(1.4); +    static const float slope = (max_volts-min_volts)/_max_rx_pga0_gain; + +    //calculate the voltage for the aux dac +    float dac_volts = gain*slope + min_volts; + +    if (wbx_debug) std::cerr << boost::format( +        "WBX TX Gain: %f dB, dac_volts: %f V" +    ) % gain % dac_volts << std::endl; + +    //write the new voltage to the aux dac +    this->get_iface()->write_aux_dac(dboard_iface::UNIT_TX, 0, dac_volts); + +    //shadow the setting (does not account for precision loss) +    _tx_pga0_gain = gain; +} + +double wbx_xcvr::set_lo_freq( +    dboard_iface::unit_t unit, +    double target_freq +){ +    if (wbx_debug) std::cerr << boost::format( +        "WBX tune: target frequency %f Mhz" +    ) % (target_freq/1e6) << std::endl; + +    //clip the input +    target_freq = std::clip(target_freq, _freq_range.min, _freq_range.max); + +    //map prescaler setting to mininmum integer divider (N) values (pg.18 prescaler) +    static const uhd::dict<int, int> prescaler_to_min_int_div = map_list_of +        (0,23) //adf4350_regs_t::PRESCALER_4_5 +        (1,75) //adf4350_regs_t::PRESCALER_8_9 +    ; + +    //map rf divider select output dividers to enums +    static const uhd::dict<int, adf4350_regs_t::rf_divider_select_t> rfdivsel_to_enum = map_list_of +        (1,  adf4350_regs_t::RF_DIVIDER_SELECT_DIV1) +        (2,  adf4350_regs_t::RF_DIVIDER_SELECT_DIV2) +        (4,  adf4350_regs_t::RF_DIVIDER_SELECT_DIV4) +        (8,  adf4350_regs_t::RF_DIVIDER_SELECT_DIV8) +        (16, adf4350_regs_t::RF_DIVIDER_SELECT_DIV16) +    ; + +    double actual_freq, pfd_freq; +    double ref_freq = this->get_iface()->get_clock_rate(unit); +    int R, BS, N, FRAC, MOD; +    int RFdiv = 1; +    adf4350_regs_t::reference_divide_by_2_t T     = adf4350_regs_t::REFERENCE_DIVIDE_BY_2_DISABLED; +    adf4350_regs_t::reference_doubler_t     D     = adf4350_regs_t::REFERENCE_DOUBLER_DISABLED;     + +    //Reference doubler for 50% duty cycle +    // if ref_freq < 12.5MHz enable regs.reference_divide_by_2 +    if(ref_freq <= 12.5e6) D = adf4350_regs_t::REFERENCE_DOUBLER_ENABLED; + +    //increase RF divider until acceptable VCO frequency +    //start with target_freq*2 because mixer has divide by 2 +    double vco_freq = target_freq*2; +    while (vco_freq < 2.2e9) { +        vco_freq *= 2; +        RFdiv *= 2; +    } + +    //use 8/9 prescaler for vco_freq > 3 GHz (pg.18 prescaler) +    adf4350_regs_t::prescaler_t prescaler = vco_freq > 3e9 ? adf4350_regs_t::PRESCALER_8_9 : adf4350_regs_t::PRESCALER_4_5; + +    /* +     * The goal here is to loop though possible R dividers, +     * band select clock dividers, N (int) dividers, and FRAC  +     * (frac) dividers. +     * +     * Calculate the N and F dividers for each set of values. +     * The loop exists when it meets all of the constraints. +     * The resulting loop values are loaded into the registers. +     * +     * from pg.21 +     * +     * f_pfd = f_ref*(1+D)/(R*(1+T)) +     * f_vco = (N + (FRAC/MOD))*f_pfd +     *    N = f_vco/f_pfd - FRAC/MOD = f_vco*((R*(T+1))/(f_ref*(1+D))) - FRAC/MOD +     * f_rf = f_vco/RFdiv) +     * f_actual = f_rf/2 +     */ +    for(R = 1; R <= 1023; R+=1){ +        //PFD input frequency = f_ref/R ... ignoring Reference doubler/divide-by-2 (D & T) +        pfd_freq = ref_freq*(1+D)/(R*(1+T)); + +        //keep the PFD frequency at or below 25MHz (Loop Filter Bandwidth) +        if (pfd_freq > 25e6) continue; + +        //ignore fractional part of tuning +        N = int(std::floor(vco_freq/pfd_freq)); + +        //keep N > minimum int divider requirement +        if (N < prescaler_to_min_int_div[prescaler]) continue; + +        for(BS=1; BS <= 255; BS+=1){ +            //keep the band select frequency at or below 100KHz +            //constraint on band select clock +            if (pfd_freq/BS > 100e3) continue; +            goto done_loop; +        } +    } done_loop: + +    //Fractional-N calculation +    MOD = 4095; //max fractional accuracy +    FRAC = int((vco_freq/pfd_freq - N)*MOD); + +    //Reference divide-by-2 for 50% duty cycle +    // if R even, move one divide by 2 to to regs.reference_divide_by_2 +    if(R % 2 == 0){ +        T = adf4350_regs_t::REFERENCE_DIVIDE_BY_2_ENABLED; +        R /= 2; +    } + +    //actual frequency calculation +    actual_freq = double((N + (double(FRAC)/double(MOD)))*ref_freq*(1+int(D))/(R*(1+int(T)))/RFdiv/2); + + +    if (wbx_debug) { +        std::cerr << boost::format("WBX Intermediates: ref=%0.2f, outdiv=%f, fbdiv=%f") % (ref_freq*(1+int(D))/(R*(1+int(T)))) % double(RFdiv*2) % double(N + double(FRAC)/double(MOD)) << std::endl; + +        std::cerr << boost::format("WBX tune: R=%d, BS=%d, N=%d, FRAC=%d, MOD=%d, T=%d, D=%d, RFdiv=%d, LD=%d" +            ) % R % BS % N % FRAC % MOD % T % D % RFdiv % get_locked(unit)<< std::endl +        << boost::format("WBX Frequencies (MHz): REQ=%0.2f, ACT=%0.2f, VCO=%0.2f, PFD=%0.2f, BAND=%0.2f" +            ) % (target_freq/1e6) % (actual_freq/1e6) % (vco_freq/1e6) % (pfd_freq/1e6) % (pfd_freq/BS/1e6) << std::endl; +    } + +    //load the register values +    adf4350_regs_t regs; + +    regs.frac_12_bit = FRAC; +    regs.int_16_bit = N; +    regs.mod_12_bit = MOD; +    regs.prescaler = prescaler; +    regs.r_counter_10_bit = R; +    regs.reference_divide_by_2 = T; +    regs.reference_doubler = D; +    regs.band_select_clock_div = BS; +    regs.rf_divider_select = rfdivsel_to_enum[RFdiv]; + +    //write the registers +    //correct power-up sequence to write registers (5, 4, 3, 2, 1, 0) +    int addr; + +    for(addr=5; addr>=0; addr--){ +        if (wbx_debug) std::cerr << boost::format( +            "WBX SPI Reg (0x%02x): 0x%08x" +        ) % addr % regs.get_reg(addr) << std::endl; +        this->get_iface()->write_spi( +            unit, spi_config_t::EDGE_RISE, +            regs.get_reg(addr), 32 +        ); +    } + +    //return the actual frequency +    if (wbx_debug) std::cerr << boost::format( +        "WBX tune: actual frequency %f Mhz" +    ) % (actual_freq/1e6) << std::endl; +    return actual_freq; +} + +/*********************************************************************** + * RX Get and Set + **********************************************************************/ +void wbx_xcvr::rx_get(const wax::obj &key_, wax::obj &val){ +    wax::obj key; std::string name; +    boost::tie(key, name) = extract_named_prop(key_); + +    //handle the get request conditioned on the key +    switch(key.as<subdev_prop_t>()){ +    case SUBDEV_PROP_NAME: +        val = get_rx_id().to_pp_string(); +        return; + +    case SUBDEV_PROP_OTHERS: +        val = prop_names_t(); //empty +        return; + +    case SUBDEV_PROP_GAIN: +        UHD_ASSERT_THROW(name == "PGA0"); +        val = _rx_pga0_gain; +        return; + +    case SUBDEV_PROP_GAIN_RANGE: +        UHD_ASSERT_THROW(name == "PGA0"); +        val = gain_range_t(0, _max_rx_pga0_gain, float(0.5)); +        return; + +    case SUBDEV_PROP_GAIN_NAMES: +        val = prop_names_t(1, "PGA0"); +        return; + +    case SUBDEV_PROP_FREQ: +        val = _rx_lo_freq; +        return; + +    case SUBDEV_PROP_FREQ_RANGE: +        val = _freq_range; +        return; + +    case SUBDEV_PROP_ANTENNA: +        val = _rx_ant; +        return; + +    case SUBDEV_PROP_ANTENNA_NAMES:{ +            prop_names_t ants = list_of("TX/RX")("RX2"); +            val = ants; +        } +        return; + +    case SUBDEV_PROP_QUADRATURE: +        val = true; +        return; + +    case SUBDEV_PROP_IQ_SWAPPED: +        val = false; +        return; + +    case SUBDEV_PROP_SPECTRUM_INVERTED: +        val = false; +        return; + +    case SUBDEV_PROP_USE_LO_OFFSET: +        val = false; +        return; + +    case SUBDEV_PROP_LO_LOCKED: +        val = this->get_locked(dboard_iface::UNIT_RX); +        return; + +    default: UHD_THROW_PROP_GET_ERROR(); +    } +} + +void wbx_xcvr::rx_set(const wax::obj &key_, const wax::obj &val){ +    wax::obj key; std::string name; +    boost::tie(key, name) = extract_named_prop(key_); + +    //handle the get request conditioned on the key +    switch(key.as<subdev_prop_t>()){ + +    case SUBDEV_PROP_FREQ: +        set_rx_lo_freq(val.as<double>()); +        return; + +    case SUBDEV_PROP_GAIN: +        UHD_ASSERT_THROW(name == "PGA0"); +        set_rx_pga0_gain(val.as<float>()); +        return; + +    case SUBDEV_PROP_ANTENNA: +        set_rx_ant(val.as<std::string>()); +        return; + +    default: UHD_THROW_PROP_SET_ERROR(); +    } +} + +/*********************************************************************** + * TX Get and Set + **********************************************************************/ +void wbx_xcvr::tx_get(const wax::obj &key_, wax::obj &val){ +    wax::obj key; std::string name; +    boost::tie(key, name) = extract_named_prop(key_); + +    //handle the get request conditioned on the key +    switch(key.as<subdev_prop_t>()){ +    case SUBDEV_PROP_NAME: +        val = get_tx_id().to_pp_string(); +        return; + +    case SUBDEV_PROP_OTHERS: +        val = prop_names_t(); //empty +        return; + +    case SUBDEV_PROP_GAIN: +        UHD_ASSERT_THROW(name == "PGA0"); +        val = _tx_pga0_gain; +        return; + +    case SUBDEV_PROP_GAIN_RANGE: +        UHD_ASSERT_THROW(name == "PGA0"); +        val = gain_range_t(0, _max_tx_pga0_gain, float(0.05)); +        return; + +    case SUBDEV_PROP_GAIN_NAMES: +        val = prop_names_t(1, "PGA0"); +        return; + +    case SUBDEV_PROP_FREQ: +        val = _tx_lo_freq; +        return; + +    case SUBDEV_PROP_FREQ_RANGE: +        val = _freq_range; +        return; + +    case SUBDEV_PROP_ANTENNA: +        val = std::string("TX/RX"); +        return; + +    case SUBDEV_PROP_ANTENNA_NAMES: +        val = prop_names_t(1, "TX/RX"); +        return; + +    case SUBDEV_PROP_QUADRATURE: +        val = true; +        return; + +    case SUBDEV_PROP_IQ_SWAPPED: +        val = false; +        return; + +    case SUBDEV_PROP_SPECTRUM_INVERTED: +        val = false; +        return; + +    case SUBDEV_PROP_USE_LO_OFFSET: +        val = false; +        return; + +    case SUBDEV_PROP_LO_LOCKED: +        val = this->get_locked(dboard_iface::UNIT_TX); +        return; + +    default: UHD_THROW_PROP_GET_ERROR(); +    } +} + +void wbx_xcvr::tx_set(const wax::obj &key_, const wax::obj &val){ +    wax::obj key; std::string name; +    boost::tie(key, name) = extract_named_prop(key_); + +    //handle the get request conditioned on the key +    switch(key.as<subdev_prop_t>()){ + +    case SUBDEV_PROP_FREQ: +        set_tx_lo_freq(val.as<double>()); +        return; + +    case SUBDEV_PROP_GAIN: +        UHD_ASSERT_THROW(name == "PGA0"); +        set_tx_pga0_gain(val.as<float>()); +        return; + +    case SUBDEV_PROP_ANTENNA: +        //its always set to tx/rx, so we only allow this value +        UHD_ASSERT_THROW(val.as<std::string>() == "TX/RX"); +        return; + +    default: UHD_THROW_PROP_SET_ERROR(); +    } +} diff --git a/host/lib/usrp/dboard/db_xcvr2450.cpp b/host/lib/usrp/dboard/db_xcvr2450.cpp index 0dfef2a0a..3472229f4 100644 --- a/host/lib/usrp/dboard/db_xcvr2450.cpp +++ b/host/lib/usrp/dboard/db_xcvr2450.cpp @@ -89,7 +89,7 @@ static const uhd::dict<std::string, gain_range_t> xcvr_rx_gain_ranges = map_list   **********************************************************************/  class xcvr2450 : public xcvr_dboard_base{  public: -    xcvr2450(ctor_args_t const& args); +    xcvr2450(ctor_args_t args);      ~xcvr2450(void);      void rx_get(const wax::obj &key, wax::obj &val); @@ -152,7 +152,7 @@ private:  /***********************************************************************   * Register the XCVR 2450 dboard   **********************************************************************/ -static dboard_base::sptr make_xcvr2450(dboard_base::ctor_args_t const& args){ +static dboard_base::sptr make_xcvr2450(dboard_base::ctor_args_t args){      return dboard_base::sptr(new xcvr2450(args));  } @@ -165,7 +165,7 @@ UHD_STATIC_BLOCK(reg_xcvr2450_dboard){  /***********************************************************************   * Structors   **********************************************************************/ -xcvr2450::xcvr2450(ctor_args_t const& args) : xcvr_dboard_base(args){ +xcvr2450::xcvr2450(ctor_args_t args) : xcvr_dboard_base(args){      //enable only the clocks we need      this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true); @@ -373,8 +373,7 @@ static max2829_regs_t::tx_baseband_gain_t gain_to_tx_bb_reg(float &gain){          gain = 5;          return max2829_regs_t::TX_BASEBAND_GAIN_5DB;      } -    BOOST_THROW_EXCEPTION(std::runtime_error("should not get here")); -    return max2829_regs_t::TX_BASEBAND_GAIN_0DB; +    UHD_ASSERT_THROW(false);  }  /*! @@ -444,7 +443,7 @@ void xcvr2450::rx_get(const wax::obj &key_, wax::obj &val){      //handle the get request conditioned on the key      switch(key.as<subdev_prop_t>()){      case SUBDEV_PROP_NAME: -        val = dboard_id::to_string(get_rx_id()); +        val = get_rx_id().to_pp_string();          return;      case SUBDEV_PROP_OTHERS: @@ -542,7 +541,7 @@ void xcvr2450::tx_get(const wax::obj &key_, wax::obj &val){      //handle the get request conditioned on the key      switch(key.as<subdev_prop_t>()){      case SUBDEV_PROP_NAME: -        val = dboard_id::to_string(get_tx_id()); +        val = get_tx_id().to_pp_string();          return;      case SUBDEV_PROP_OTHERS: diff --git a/host/lib/usrp/dboard_base.cpp b/host/lib/usrp/dboard_base.cpp index 68e4743d1..bd4b37ef3 100644 --- a/host/lib/usrp/dboard_base.cpp +++ b/host/lib/usrp/dboard_base.cpp @@ -15,6 +15,7 @@  // along with this program.  If not, see <http://www.gnu.org/licenses/>.  // +#include "dboard_ctor_args.hpp"  #include <uhd/usrp/dboard_base.hpp>  #include <boost/format.hpp>  #include <stdexcept> @@ -24,43 +25,48 @@ using namespace uhd::usrp;  /***********************************************************************   * dboard_base dboard dboard_base class   **********************************************************************/ -dboard_base::dboard_base(ctor_args_t const& args){ -    boost::tie(_subdev_name, _dboard_iface, _rx_id, _tx_id) = args; +struct dboard_base::dboard_base_impl{ +    ctor_args_impl args; +    dboard_base_impl(ctor_args_t args) : args(*args){} +}; + +dboard_base::dboard_base(ctor_args_t args){ +    _impl = new dboard_base_impl(args);  }  dboard_base::~dboard_base(void){ -    /* NOP */ +   delete _impl;  }  std::string dboard_base::get_subdev_name(void){ -    return _subdev_name; +    return _impl->args.sd_name;  }  dboard_iface::sptr dboard_base::get_iface(void){ -    return _dboard_iface; +    return _impl->args.db_iface;  }  dboard_id_t dboard_base::get_rx_id(void){ -    return _rx_id; +    return _impl->args.rx_id;  }  dboard_id_t dboard_base::get_tx_id(void){ -    return _tx_id; +    return _impl->args.tx_id;  }  /***********************************************************************   * xcvr dboard dboard_base class   **********************************************************************/ -xcvr_dboard_base::xcvr_dboard_base(ctor_args_t const& args) : dboard_base(args){ -    if (get_rx_id() == dboard_id::NONE){ +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(              "cannot create xcvr board when the rx id is \"%s\"" -        ) % dboard_id::to_string(dboard_id::NONE))); +        ) % dboard_id_t::none().to_pp_string()));      } -    if (get_tx_id() == dboard_id::NONE){ +    if (get_tx_id() == dboard_id_t::none()){          throw std::runtime_error(str(boost::format(              "cannot create xcvr board when the tx id is \"%s\"" -        ) % dboard_id::to_string(dboard_id::NONE))); +        ) % dboard_id_t::none().to_pp_string()));      }  } @@ -71,12 +77,12 @@ xcvr_dboard_base::~xcvr_dboard_base(void){  /***********************************************************************   * rx dboard dboard_base class   **********************************************************************/ -rx_dboard_base::rx_dboard_base(ctor_args_t const& args) : dboard_base(args){ -    if (get_tx_id() != dboard_id::NONE){ +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(              "cannot create rx board when the tx id is \"%s\""              " -> expected a tx id of \"%s\"" -        ) % dboard_id::to_string(get_tx_id()) % dboard_id::to_string(dboard_id::NONE))); +        ) % get_tx_id().to_pp_string() % dboard_id_t::none().to_pp_string()));      }  } @@ -95,12 +101,12 @@ void rx_dboard_base::tx_set(const wax::obj &, const wax::obj &){  /***********************************************************************   * tx dboard dboard_base class   **********************************************************************/ -tx_dboard_base::tx_dboard_base(ctor_args_t const& args) : dboard_base(args){ -    if (get_rx_id() != dboard_id::NONE){ +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(              "cannot create tx board when the rx id is \"%s\""              " -> expected a rx id of \"%s\"" -        ) % dboard_id::to_string(get_rx_id()) % dboard_id::to_string(dboard_id::NONE))); +        ) % get_rx_id().to_pp_string() % dboard_id_t::none().to_pp_string()));      }  } diff --git a/host/lib/usrp/dboard_ctor_args.hpp b/host/lib/usrp/dboard_ctor_args.hpp new file mode 100644 index 000000000..13abe79e8 --- /dev/null +++ b/host/lib/usrp/dboard_ctor_args.hpp @@ -0,0 +1,32 @@ +// +// 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_DBOARD_CTOR_ARGS_HPP +#define INCLUDED_DBOARD_CTOR_ARGS_HPP + +#include <uhd/usrp/dboard_id.hpp> +#include <uhd/usrp/dboard_base.hpp> +#include <uhd/usrp/dboard_iface.hpp> +#include <string> + +struct uhd::usrp::dboard_base::ctor_args_impl{ +    std::string               sd_name; +    dboard_iface::sptr        db_iface; +    dboard_id_t               rx_id, tx_id; +}; + +#endif /* INCLUDED_DBOARD_CTOR_ARGS_HPP */ diff --git a/host/lib/usrp/dboard_eeprom.cpp b/host/lib/usrp/dboard_eeprom.cpp index 54e7a4fd9..fa3631948 100644 --- a/host/lib/usrp/dboard_eeprom.cpp +++ b/host/lib/usrp/dboard_eeprom.cpp @@ -80,19 +80,20 @@ dboard_eeprom_t::dboard_eeprom_t(const byte_vector_t &bytes){          UHD_ASSERT_THROW(bytes.size() >= DB_EEPROM_CLEN);          UHD_ASSERT_THROW(bytes[DB_EEPROM_MAGIC] == DB_EEPROM_MAGIC_VALUE);          UHD_ASSERT_THROW(bytes[DB_EEPROM_CHKSUM] == checksum(bytes)); -        id = \ -            (boost::uint16_t(bytes[DB_EEPROM_ID_LSB]) << 0) | -            (boost::uint16_t(bytes[DB_EEPROM_ID_MSB]) << 8) ; +        id = dboard_id_t::from_uint16(0 +            | (boost::uint16_t(bytes[DB_EEPROM_ID_LSB]) << 0) +            | (boost::uint16_t(bytes[DB_EEPROM_ID_MSB]) << 8) +        );      }catch(const uhd::assert_error &){ -        id = dboard_id::NONE; +        id = dboard_id_t::none();      }  }  byte_vector_t dboard_eeprom_t::get_eeprom_bytes(void){      byte_vector_t bytes(DB_EEPROM_CLEN, 0); //defaults to all zeros      bytes[DB_EEPROM_MAGIC] = DB_EEPROM_MAGIC_VALUE; -    bytes[DB_EEPROM_ID_LSB] = boost::uint8_t(id >> 0); -    bytes[DB_EEPROM_ID_MSB] = boost::uint8_t(id >> 8); +    bytes[DB_EEPROM_ID_LSB] = boost::uint8_t(id.to_uint16() >> 0); +    bytes[DB_EEPROM_ID_MSB] = boost::uint8_t(id.to_uint16() >> 8);      bytes[DB_EEPROM_CHKSUM] = checksum(bytes);      return bytes;  } diff --git a/host/lib/usrp/dboard_id.cpp b/host/lib/usrp/dboard_id.cpp new file mode 100644 index 000000000..3028d2a3b --- /dev/null +++ b/host/lib/usrp/dboard_id.cpp @@ -0,0 +1,68 @@ +// +// 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/>. +// + +#include <uhd/usrp/dboard_id.hpp> +#include <boost/lexical_cast.hpp> +#include <boost/format.hpp> +#include <sstream> +#include <iostream> + +using namespace uhd::usrp; + +dboard_id_t::dboard_id_t(boost::uint16_t id){ +    _id = id; +} + +dboard_id_t dboard_id_t::none(void){ +    return dboard_id_t(); +} + +dboard_id_t dboard_id_t::from_uint16(boost::uint16_t uint16){ +    return dboard_id_t(uint16); +} + +boost::uint16_t dboard_id_t::to_uint16(void) const{ +    return _id; +} + +//used with lexical cast to parse a hex string +template <class T> struct to_hex{ +    T value; +    operator T() const {return value;} +    friend std::istream& operator>>(std::istream& in, to_hex& out){ +        in >> std::hex >> out.value; +        return in; +    } +}; + +dboard_id_t dboard_id_t::from_string(const std::string &string){ +    if (string.substr(0, 2) == "0x"){ +        return dboard_id_t::from_uint16(boost::lexical_cast<to_hex<boost::uint16_t> >(string)); +    } +    return dboard_id_t::from_uint16(boost::lexical_cast<boost::uint16_t>(string)); +} + +std::string dboard_id_t::to_string(void) const{ +    return str(boost::format("0x%04x") % this->to_uint16()); +} + +//Note: to_pp_string is implemented in the dboard manager +//because it needs access to the dboard registration table + +bool uhd::usrp::operator==(const dboard_id_t &lhs, const dboard_id_t &rhs){ +    return lhs.to_uint16() == rhs.to_uint16(); +} diff --git a/host/lib/usrp/dboard_manager.cpp b/host/lib/usrp/dboard_manager.cpp index 390c1d3c9..8161727e5 100644 --- a/host/lib/usrp/dboard_manager.cpp +++ b/host/lib/usrp/dboard_manager.cpp @@ -15,6 +15,7 @@  // along with this program.  If not, see <http://www.gnu.org/licenses/>.  // +#include "dboard_ctor_args.hpp"  #include <uhd/usrp/dboard_manager.hpp>  #include <uhd/usrp/subdev_props.hpp>  #include <uhd/utils/gain_handler.hpp> @@ -26,6 +27,7 @@  #include <boost/bind.hpp>  #include <boost/foreach.hpp>  #include <boost/assign/list_of.hpp> +#include <iostream>  using namespace uhd;  using namespace uhd::usrp; @@ -49,15 +51,18 @@ 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( -            "The dboard id 0x%04x is already registered to %s." -        ) % dboard_id % dboard_id::to_string(dboard_id))); +            "The dboard id %s is already registered to %s." +        ) % dboard_id.to_string() % dboard_id.to_pp_string()));      }      get_id_to_args_map()[dboard_id] = args_t(dboard_ctor, name, subdev_names);  } -std::string dboard_id::to_string(const dboard_id_t &id){ -    std::string name = (get_id_to_args_map().has_key(id))? get_id_to_args_map()[id].get<1>() : "unknown"; -    return str(boost::format("%s (0x%04x)") % name % id); +std::string dboard_id_t::to_pp_string(void) const{ +    std::string name = "unknown"; +    if (get_id_to_args_map().has_key(*this)){ +        name = get_id_to_args_map()[*this].get<1>(); +    } +    return str(boost::format("%s (%s)") % name % this->to_string());  }  /*********************************************************************** @@ -162,26 +167,27 @@ dboard_manager::sptr dboard_manager::make(   * implementation class methods   **********************************************************************/  static args_t get_dboard_args( -    dboard_id_t dboard_id, -    std::string const& xx_type +    dboard_iface::unit_t unit, +    dboard_id_t dboard_id  ){ -    //special case, its rx and the none id (0xffff) -    if (xx_type == "rx" and dboard_id == dboard_id::NONE){ -        return get_dboard_args(0x0001, xx_type); -    } - -    //special case, its tx and the none id (0xffff) -    if (xx_type == "tx" and dboard_id == dboard_id::NONE){ -        return get_dboard_args(0x0000, xx_type); +    //special case, the none id was provided, use the following ids +    if (dboard_id == dboard_id_t::none()){ +        std::cerr << boost::format( +            "Warning: unregistered dboard id: %s" +            " -> defaulting to a basic board" +        ) % dboard_id.to_pp_string() << std::endl; +        UHD_ASSERT_THROW(get_id_to_args_map().has_key(0x0001)); +        UHD_ASSERT_THROW(get_id_to_args_map().has_key(0x0000)); +        switch(unit){ +        case dboard_iface::UNIT_RX: return get_dboard_args(unit, 0x0001); +        case dboard_iface::UNIT_TX: return get_dboard_args(unit, 0x0000); +        default: UHD_ASSERT_THROW(false); +        }      }      //verify that there is a registered constructor for this id      if (not get_id_to_args_map().has_key(dboard_id)){ -        /*throw std::runtime_error(str( -            boost::format("Unregistered %s dboard id: %s") -            % xx_type % dboard_id::to_string(dboard_id) -        ));*/ -        return get_dboard_args(dboard_id::NONE, xx_type); +        return get_dboard_args(unit, dboard_id_t::none());      }      //return the dboard args for this id @@ -196,21 +202,26 @@ dboard_manager_impl::dboard_manager_impl(      _iface = iface;      dboard_ctor_t rx_dboard_ctor; std::string rx_name; prop_names_t rx_subdevs; -    boost::tie(rx_dboard_ctor, rx_name, rx_subdevs) = get_dboard_args(rx_dboard_id, "rx"); +    boost::tie(rx_dboard_ctor, rx_name, rx_subdevs) = get_dboard_args(dboard_iface::UNIT_RX, rx_dboard_id);      dboard_ctor_t tx_dboard_ctor; std::string tx_name; prop_names_t tx_subdevs; -    boost::tie(tx_dboard_ctor, tx_name, tx_subdevs) = get_dboard_args(tx_dboard_id, "tx"); +    boost::tie(tx_dboard_ctor, tx_name, tx_subdevs) = get_dboard_args(dboard_iface::UNIT_TX, tx_dboard_id);      //initialize the gpio pins before creating subdevs      set_nice_dboard_if(); +    //dboard constructor args +    dboard_base::ctor_args_impl db_ctor_args; +    db_ctor_args.db_iface = iface; +      //make xcvr subdevs (make one subdev for both rx and tx dboards)      if (rx_dboard_ctor == tx_dboard_ctor){          UHD_ASSERT_THROW(rx_subdevs == tx_subdevs);          BOOST_FOREACH(const std::string &subdev, rx_subdevs){ -            dboard_base::sptr xcvr_dboard = rx_dboard_ctor( -                dboard_base::ctor_args_t(subdev, iface, rx_dboard_id, tx_dboard_id) -            ); +            db_ctor_args.sd_name = subdev; +            db_ctor_args.rx_id = rx_dboard_id; +            db_ctor_args.tx_id = tx_dboard_id; +            dboard_base::sptr xcvr_dboard = rx_dboard_ctor(&db_ctor_args);              //create a rx proxy for this xcvr board              _rx_dboards[subdev] = subdev_proxy::sptr(                  new subdev_proxy(xcvr_dboard, subdev_proxy::RX_TYPE) @@ -226,9 +237,10 @@ dboard_manager_impl::dboard_manager_impl(      else{          //make the rx subdevs          BOOST_FOREACH(const std::string &subdev, rx_subdevs){ -            dboard_base::sptr rx_dboard = rx_dboard_ctor( -                dboard_base::ctor_args_t(subdev, iface, rx_dboard_id, dboard_id::NONE) -            ); +            db_ctor_args.sd_name = subdev; +            db_ctor_args.rx_id = rx_dboard_id; +            db_ctor_args.tx_id = dboard_id_t::none(); +            dboard_base::sptr rx_dboard = rx_dboard_ctor(&db_ctor_args);              //create a rx proxy for this rx board              _rx_dboards[subdev] = subdev_proxy::sptr(                  new subdev_proxy(rx_dboard, subdev_proxy::RX_TYPE) @@ -236,9 +248,10 @@ dboard_manager_impl::dboard_manager_impl(          }          //make the tx subdevs          BOOST_FOREACH(const std::string &subdev, tx_subdevs){ -            dboard_base::sptr tx_dboard = tx_dboard_ctor( -                dboard_base::ctor_args_t(subdev, iface, dboard_id::NONE, tx_dboard_id) -            ); +            db_ctor_args.sd_name = subdev; +            db_ctor_args.rx_id = dboard_id_t::none(); +            db_ctor_args.tx_id = tx_dboard_id; +            dboard_base::sptr tx_dboard = tx_dboard_ctor(&db_ctor_args);              //create a tx proxy for this tx board              _tx_dboards[subdev] = subdev_proxy::sptr(                  new subdev_proxy(tx_dboard, subdev_proxy::TX_TYPE) diff --git a/host/lib/usrp/usrp2/CMakeLists.txt b/host/lib/usrp/usrp2/CMakeLists.txt new file mode 100644 index 000000000..f9907e21e --- /dev/null +++ b/host/lib/usrp/usrp2/CMakeLists.txt @@ -0,0 +1,29 @@ +# +# 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/>. +# + +#This file will be included by cmake, use absolute paths! + +LIBUHD_APPEND_SOURCES( +    ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/clock_control.cpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dboard_impl.cpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dboard_iface.cpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dsp_impl.cpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/io_impl.cpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/mboard_impl.cpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_iface.cpp +    ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_impl.cpp +) diff --git a/host/lib/usrp/usrp2/dboard_iface.cpp b/host/lib/usrp/usrp2/dboard_iface.cpp index 74d80163c..372a5af07 100644 --- a/host/lib/usrp/usrp2/dboard_iface.cpp +++ b/host/lib/usrp/usrp2/dboard_iface.cpp @@ -29,6 +29,7 @@  using namespace uhd;  using namespace uhd::usrp; +using namespace boost::assign;  class usrp2_dboard_iface : public dboard_iface{  public: @@ -122,49 +123,42 @@ double usrp2_dboard_iface::get_clock_rate(unit_t){  void usrp2_dboard_iface::set_clock_enabled(unit_t unit, bool enb){      switch(unit){ -    case UNIT_RX: -        _clk_ctrl->enable_rx_dboard_clock(enb); -        return; -    case UNIT_TX: -        _clk_ctrl->enable_tx_dboard_clock(enb); -        return; +    case UNIT_RX: _clk_ctrl->enable_rx_dboard_clock(enb); return; +    case UNIT_TX: _clk_ctrl->enable_tx_dboard_clock(enb); return;      }  }  /***********************************************************************   * GPIO   **********************************************************************/ -static int unit_to_shift(dboard_iface::unit_t unit){ -    switch(unit){ -    case dboard_iface::UNIT_RX: return 0; -    case dboard_iface::UNIT_TX: return 16; -    } -    throw std::runtime_error("unknown unit type"); -} +static const uhd::dict<dboard_iface::unit_t, int> unit_to_shift = map_list_of +    (dboard_iface::UNIT_RX, 0) +    (dboard_iface::UNIT_TX, 16) +;  void usrp2_dboard_iface::set_gpio_ddr(unit_t unit, boost::uint16_t value){      _ddr_shadow = \ -        (_ddr_shadow & ~(0xffff << unit_to_shift(unit))) | -        (boost::uint32_t(value) << unit_to_shift(unit)); +        (_ddr_shadow & ~(0xffff << unit_to_shift[unit])) | +        (boost::uint32_t(value) << unit_to_shift[unit]);      _iface->poke32(FR_GPIO_DDR, _ddr_shadow);  }  boost::uint16_t usrp2_dboard_iface::read_gpio(unit_t unit){ -    return boost::uint16_t(_iface->peek32(FR_GPIO_IO) >> unit_to_shift(unit)); +    return boost::uint16_t(_iface->peek32(FR_GPIO_IO) >> unit_to_shift[unit]);  }  void usrp2_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_t value){      //define mapping of unit to atr regs to register address      static const uhd::dict<          unit_t, uhd::dict<atr_reg_t, boost::uint32_t> -    > unit_to_atr_to_addr = boost::assign::map_list_of -        (UNIT_RX, boost::assign::map_list_of +    > unit_to_atr_to_addr = map_list_of +        (UNIT_RX, map_list_of              (ATR_REG_IDLE,        FR_ATR_IDLE_RXSIDE)              (ATR_REG_TX_ONLY,     FR_ATR_INTX_RXSIDE)              (ATR_REG_RX_ONLY,     FR_ATR_INRX_RXSIDE)              (ATR_REG_FULL_DUPLEX, FR_ATR_FULL_RXSIDE)          ) -        (UNIT_TX, boost::assign::map_list_of +        (UNIT_TX, map_list_of              (ATR_REG_IDLE,        FR_ATR_IDLE_TXSIDE)              (ATR_REG_TX_ONLY,     FR_ATR_INTX_TXSIDE)              (ATR_REG_RX_ONLY,     FR_ATR_INRX_TXSIDE) @@ -177,19 +171,10 @@ void usrp2_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_t  /***********************************************************************   * SPI   **********************************************************************/ -/*! - * Static function to convert a unit type enum - * to an over-the-wire value for the spi device. - * \param unit the dboard interface unit type enum - * \return an over the wire representation - */ -static boost::uint8_t unit_to_otw_spi_dev(dboard_iface::unit_t unit){ -    switch(unit){ -    case dboard_iface::UNIT_TX: return SPI_SS_TX_DB; -    case dboard_iface::UNIT_RX: return SPI_SS_RX_DB; -    } -    throw std::invalid_argument("unknown unit type"); -} +static const uhd::dict<dboard_iface::unit_t, int> unit_to_spi_dev = map_list_of +    (dboard_iface::UNIT_TX, SPI_SS_TX_DB) +    (dboard_iface::UNIT_RX, SPI_SS_RX_DB) +;  void usrp2_dboard_iface::write_spi(      unit_t unit, @@ -197,7 +182,7 @@ void usrp2_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->transact_spi(unit_to_spi_dev[unit], config, data, num_bits, false /*no rb*/);  }  boost::uint32_t usrp2_dboard_iface::read_write_spi( @@ -206,7 +191,7 @@ boost::uint32_t usrp2_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->transact_spi(unit_to_spi_dev[unit], config, data, num_bits, true /*rb*/);  }  /*********************************************************************** @@ -224,7 +209,7 @@ byte_vector_t usrp2_dboard_iface::read_i2c(boost::uint8_t addr, size_t num_bytes   * Aux DAX/ADC   **********************************************************************/  void usrp2_dboard_iface::_write_aux_dac(unit_t unit){ -    static const uhd::dict<unit_t, int> unit_to_spi_dac = boost::assign::map_list_of +    static const uhd::dict<unit_t, int> unit_to_spi_dac = map_list_of          (UNIT_RX, SPI_SS_RX_DAC)          (UNIT_TX, SPI_SS_TX_DAC)      ; @@ -248,7 +233,7 @@ void usrp2_dboard_iface::write_aux_dac(unit_t unit, int which, float value){  }  float usrp2_dboard_iface::read_aux_adc(unit_t unit, int which){ -    static const uhd::dict<unit_t, int> unit_to_spi_adc = boost::assign::map_list_of +    static const uhd::dict<unit_t, int> unit_to_spi_adc = map_list_of          (UNIT_RX, SPI_SS_RX_ADC)          (UNIT_TX, SPI_SS_TX_ADC)      ; diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp index bd61ac376..195a9bc53 100644 --- a/host/lib/usrp/usrp2/dsp_impl.cpp +++ b/host/lib/usrp/usrp2/dsp_impl.cpp @@ -52,6 +52,23 @@ static boost::uint32_t calculate_freq_word_and_update_actual_freq(double &freq,      return freq_word;  } +// Check if requested decim/interp rate is: +//      multiple of 4, enable two halfband filters +//      multiple of 2, enable one halfband filter +//      handle remainder in CIC +static boost::uint32_t calculate_cic_word(size_t rate){ +    int hb0 = 0, hb1 = 0; +    if (not (rate & 0x1)){ +        hb0 = 1; +        rate /= 2; +    } +    if (not (rate & 0x1)){ +        hb1 = 1; +        rate /= 2; +    } +    return (hb1 << 9) | (hb0 << 8) | (rate & 0xff); +} +  static boost::uint32_t calculate_iq_scale_word(boost::int16_t i, boost::int16_t q){      return (boost::uint16_t(i) << 16) | (boost::uint16_t(q) << 0);  } @@ -81,7 +98,7 @@ void usrp2_impl::init_ddc_config(void){  void usrp2_impl::update_ddc_config(void){      //set the decimation -    _iface->poke32(FR_DSP_RX_DECIM_RATE, _ddc_decim); +    _iface->poke32(FR_DSP_RX_DECIM_RATE, calculate_cic_word(_ddc_decim));      //set the scaling      static const boost::int16_t default_rx_scale_iq = 1024; @@ -160,15 +177,14 @@ void usrp2_impl::init_duc_config(void){  void usrp2_impl::update_duc_config(void){      // Calculate CIC interpolation (i.e., without halfband interpolators) -    size_t tmp_interp = _duc_interp; -    while(tmp_interp > 128) tmp_interp /= 2; +    size_t tmp_interp = calculate_cic_word(_duc_interp) & 0xff;      // Calculate closest multiplier constant to reverse gain absent scale multipliers      double interp_cubed = std::pow(double(tmp_interp), 3);      boost::int16_t scale = rint((4096*std::pow(2, ceil(log2(interp_cubed))))/(1.65*interp_cubed));      //set the interpolation -    _iface->poke32(FR_DSP_TX_INTERP_RATE, _ddc_decim); +    _iface->poke32(FR_DSP_TX_INTERP_RATE, calculate_cic_word(_duc_interp));      //set the scaling      _iface->poke32(FR_DSP_TX_SCALE_IQ, calculate_iq_scale_word(scale, scale)); diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index a2e99c824..7c9d003ce 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -39,6 +39,9 @@ void usrp2_impl::io_init(void){      //initially empty copy buffer      _rx_copy_buff = asio::buffer("", 0); +    //init the expected rx seq number +    _rx_stream_id_to_packet_seq[0] = 0; +      //send a small data packet so the usrp2 knows the udp source port      managed_send_buffer::sptr send_buff = _data_transport->get_send_buff();      boost::uint32_t data = htonl(USRP2_INVALID_VRT_HEADER); diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 2b974fb9b..1dde8c054 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -113,31 +113,23 @@ device::sptr usrp2::make(const device_addr_t &device_addr){          device_addr["addr"], num2str(USRP2_UDP_CTRL_PORT)      ); -    //create a data transport -    udp_zero_copy::sptr data_transport = udp_zero_copy::make( -        device_addr["addr"], num2str(USRP2_UDP_DATA_PORT) -    ); - -    //resize the recv data transport buffers +    //extract the receive and send buffer sizes +    size_t recv_buff_size = 0, send_buff_size= 0 ;      if (device_addr.has_key("recv_buff_size")){ -        size_t num_byes = size_t(boost::lexical_cast<double>(device_addr["recv_buff_size"])); -        size_t actual_bytes = data_transport->resize_recv_buff_size(num_byes); -        if (num_byes != actual_bytes) std::cout << boost::format( -            "Target recv buffer size: %d\n" -            "Actual recv byffer size: %d" -        ) % num_byes % actual_bytes << std::endl; +        recv_buff_size = size_t(boost::lexical_cast<double>(device_addr["recv_buff_size"]));      } - -    //resize the send data transport buffers      if (device_addr.has_key("send_buff_size")){ -        size_t num_byes = size_t(boost::lexical_cast<double>(device_addr["send_buff_size"])); -        size_t actual_bytes = data_transport->resize_send_buff_size(num_byes); -        if (num_byes != actual_bytes) std::cout << boost::format( -            "Target send buffer size: %d\n" -            "Actual send byffer size: %d" -        ) % num_byes % actual_bytes << std::endl; +        send_buff_size = size_t(boost::lexical_cast<double>(device_addr["send_buff_size"]));      } +    //create a data transport +    udp_zero_copy::sptr data_transport = udp_zero_copy::make( +        device_addr["addr"], +        num2str(USRP2_UDP_DATA_PORT), +        recv_buff_size, +        send_buff_size +    ); +      //create the usrp2 implementation guts      return device::sptr(          new usrp2_impl(ctrl_transport, data_transport) diff --git a/host/lib/utils.cpp b/host/lib/utils.cpp index 3a1e5aa3f..d2f4dfc6e 100644 --- a/host/lib/utils.cpp +++ b/host/lib/utils.cpp @@ -15,11 +15,20 @@  // along with this program.  If not, see <http://www.gnu.org/licenses/>.  // +#include <uhd/utils/assert.hpp>  #include <uhd/utils/props.hpp> +#include <stdexcept>  using namespace uhd;  /*********************************************************************** + * Assert + **********************************************************************/ +assert_error::assert_error(const std::string &what) : std::runtime_error(what){ +    /* NOP */ +} + +/***********************************************************************   * Props   **********************************************************************/  named_prop_t::named_prop_t( diff --git a/host/test/CMakeLists.txt b/host/test/CMakeLists.txt index 1791d9082..61b0b503d 100644 --- a/host/test/CMakeLists.txt +++ b/host/test/CMakeLists.txt @@ -21,6 +21,8 @@  ADD_EXECUTABLE(main_test      main_test.cpp      addr_test.cpp +    dict_test.cpp +    error_test.cpp      gain_handler_test.cpp      vrt_test.cpp      wax_test.cpp diff --git a/host/test/addr_test.cpp b/host/test/addr_test.cpp index 93b7cc0df..0c50200d6 100644 --- a/host/test/addr_test.cpp +++ b/host/test/addr_test.cpp @@ -18,6 +18,7 @@  #include <boost/test/unit_test.hpp>  #include <uhd/types/mac_addr.hpp>  #include <uhd/types/device_addr.hpp> +#include <uhd/usrp/dboard_id.hpp>  #include <boost/assign/list_of.hpp>  #include <boost/foreach.hpp>  #include <algorithm> @@ -41,8 +42,8 @@ BOOST_AUTO_TEST_CASE(test_device_addr){      dev_addr["key2"] = "val2";      //convert to and from args string -    std::cout << "Pretty Print: " << std::endl << dev_addr.to_string(); -    std::string args_str = dev_addr.to_args_str(); +    std::cout << "Pretty Print: " << std::endl << dev_addr.to_pp_string(); +    std::string args_str = dev_addr.to_string();      std::cout << "Args String: " << args_str << std::endl;      uhd::device_addr_t new_dev_addr(args_str); @@ -65,3 +66,15 @@ BOOST_AUTO_TEST_CASE(test_device_addr){          new_dev_addr_vals.begin(), new_dev_addr_vals.end()      );  } + +BOOST_AUTO_TEST_CASE(test_dboard_id){ +    std::cout << "Testing dboard id..." << std::endl; + +    using namespace uhd::usrp; + +    BOOST_CHECK(dboard_id_t() == dboard_id_t::none()); +    BOOST_CHECK_EQUAL(dboard_id_t().to_uint16(), dboard_id_t::none().to_uint16()); +    BOOST_CHECK_EQUAL(dboard_id_t::from_string("0x1234").to_uint16(), 0x1234); +    BOOST_CHECK_EQUAL(dboard_id_t::from_string("1234").to_uint16(), 1234); +    std::cout << "Pretty Print: " << std::endl << dboard_id_t::none().to_pp_string(); +} diff --git a/host/test/dict_test.cpp b/host/test/dict_test.cpp new file mode 100644 index 000000000..0501a7878 --- /dev/null +++ b/host/test/dict_test.cpp @@ -0,0 +1,72 @@ +// +// 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/>. +// + +#include <boost/test/unit_test.hpp> +#include <uhd/types/dict.hpp> +#include <boost/assign/list_of.hpp> + +BOOST_AUTO_TEST_CASE(test_dict_init){ +    uhd::dict<int, int> d; +    d[-1] = 3; +    d[0] = 4; +    d[1] = 5; +    BOOST_CHECK(d.has_key(0)); +    BOOST_CHECK(not d.has_key(2)); +    BOOST_CHECK(d.keys()[1] == 0); +    BOOST_CHECK(d.vals()[1] == 4); +    BOOST_CHECK_EQUAL(d[-1], 3); +} + +BOOST_AUTO_TEST_CASE(test_dict_assign){ +    uhd::dict<int, int> d = boost::assign::map_list_of +        (-1, 3) +        (0, 4) +        (1, 5) +    ; +    BOOST_CHECK(d.has_key(0)); +    BOOST_CHECK(not d.has_key(2)); +    BOOST_CHECK(d.keys()[1] == 0); +    BOOST_CHECK(d.vals()[1] == 4); +    BOOST_CHECK_EQUAL(d[-1], 3); +} + +BOOST_AUTO_TEST_CASE(test_const_dict){ +    const uhd::dict<int, int> d = boost::assign::map_list_of +        (-1, 3) +        (0, 4) +        (1, 5) +    ; +    BOOST_CHECK(d.has_key(0)); +    BOOST_CHECK(not d.has_key(2)); +    BOOST_CHECK(d.keys()[1] == 0); +    BOOST_CHECK(d.vals()[1] == 4); +    BOOST_CHECK_EQUAL(d[-1], 3); +    BOOST_CHECK_THROW(d[2], std::exception); +} + +BOOST_AUTO_TEST_CASE(test_dict_pop){ +    uhd::dict<int, int> d = boost::assign::map_list_of +        (-1, 3) +        (0, 4) +        (1, 5) +    ; +    BOOST_CHECK(d.has_key(0)); +    BOOST_CHECK_EQUAL(d.pop(0), 4); +    BOOST_CHECK(not d.has_key(0)); +    BOOST_CHECK(d.keys()[0] == -1); +    BOOST_CHECK(d.keys()[1] == 1); +} diff --git a/host/test/error_test.cpp b/host/test/error_test.cpp new file mode 100644 index 000000000..c76a15ab7 --- /dev/null +++ b/host/test/error_test.cpp @@ -0,0 +1,48 @@ +// +// 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/>. +// + +#include <boost/test/unit_test.hpp> +#include <uhd/utils/assert.hpp> +#include <vector> +#include <iostream> + +BOOST_AUTO_TEST_CASE(test_assert_has){ +    std::vector<int> vec; +    vec.push_back(2); +    vec.push_back(3); +    vec.push_back(5); + +    //verify the std::has utility +    BOOST_CHECK(std::has(vec, 2)); +    BOOST_CHECK(not std::has(vec, 1)); + +    std::cout << "The output of the assert_has error:" << std::endl; +    try{ +        uhd::assert_has(vec, 1, "prime"); +    }catch(const std::exception &e){ +        std::cout << e.what() << std::endl; +    } +} + +BOOST_AUTO_TEST_CASE(test_assert_throw){ +    std::cout << "The output of the assert throw error:" << std::endl; +    try{ +        UHD_ASSERT_THROW(2 + 2 == 5); +    }catch(const std::exception &e){ +        std::cout << e.what() << std::endl; +    } +} diff --git a/host/utils/uhd_burn_db_eeprom.cpp b/host/utils/uhd_burn_db_eeprom.cpp index c07b43f16..dfd9decba 100644 --- a/host/utils/uhd_burn_db_eeprom.cpp +++ b/host/utils/uhd_burn_db_eeprom.cpp @@ -24,11 +24,9 @@  #include <uhd/usrp/mboard_props.hpp>  #include <uhd/usrp/dboard_props.hpp>  #include <boost/program_options.hpp> -#include <boost/lexical_cast.hpp>  #include <boost/format.hpp>  #include <boost/assign.hpp>  #include <iostream> -#include <sstream>  using namespace uhd;  using namespace uhd::usrp; @@ -89,14 +87,14 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      if (vm.count("id") == 0){          std::cout << boost::format("Getting dbid on %s dboard...") % prefix << std::endl;          dboard_id_t id = dboard[DBOARD_PROP_DBOARD_ID].as<dboard_id_t>(); -        std::cout << boost::format("  Current dbid: %s") % dboard_id::to_string(id) << std::endl; +        std::cout << boost::format("  Current dbid: %s") % id.to_pp_string() << std::endl;      }      //write a new dboard id to eeprom      else{ -        dboard_id_t id = boost::lexical_cast<to_hex<dboard_id_t> >(vm["id"].as<std::string>()); +        dboard_id_t id = dboard_id_t::from_string(vm["id"].as<std::string>());          std::cout << boost::format("Setting dbid on %s dboard...") % prefix << std::endl; -        std::cout << boost::format("  New dbid: %s") % dboard_id::to_string(id) << std::endl; +        std::cout << boost::format("  New dbid: %s") % id.to_pp_string() << std::endl;          dboard[DBOARD_PROP_DBOARD_ID] = id;      } diff --git a/host/utils/uhd_find_devices.cpp b/host/utils/uhd_find_devices.cpp index 69e550fd4..b778eeb68 100644 --- a/host/utils/uhd_find_devices.cpp +++ b/host/utils/uhd_find_devices.cpp @@ -52,7 +52,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){          std::cout << "--------------------------------------------------" << std::endl;          std::cout << "-- UHD Device " << i << std::endl;          std::cout << "--------------------------------------------------" << std::endl; -        std::cout << device_addrs[i].to_string() << std::endl << std::endl; +        std::cout << device_addrs[i].to_pp_string() << std::endl << std::endl;          //uhd::device::make(device_addrs[i]); //test make      } | 
