diff options
Diffstat (limited to 'host/include')
| -rw-r--r-- | host/include/uhd/config.hpp | 9 | ||||
| -rw-r--r-- | host/include/uhd/convert.hpp | 3 | ||||
| -rw-r--r-- | host/include/uhd/transport/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | host/include/uhd/transport/chdr.hpp | 113 | ||||
| -rw-r--r-- | host/include/uhd/transport/nirio/nirio_driver_iface.h | 14 | ||||
| -rw-r--r-- | host/include/uhd/transport/nirio/nirio_fifo.h | 4 | ||||
| -rw-r--r-- | host/include/uhd/transport/usb_device_handle.hpp | 3 | ||||
| -rw-r--r-- | host/include/uhd/transport/vrt_if_packet.hpp | 76 | ||||
| -rw-r--r-- | host/include/uhd/types/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | host/include/uhd/types/byte_vector.hpp | 48 | ||||
| -rw-r--r-- | host/include/uhd/types/dict.hpp | 19 | ||||
| -rw-r--r-- | host/include/uhd/types/dict.ipp | 14 | ||||
| -rw-r--r-- | host/include/uhd/types/direction.hpp | 2 | ||||
| -rw-r--r-- | host/include/uhd/types/filters.hpp | 286 | ||||
| -rw-r--r-- | host/include/uhd/types/sid.hpp | 238 | ||||
| -rw-r--r-- | host/include/uhd/usrp/multi_usrp.hpp | 114 | ||||
| -rw-r--r-- | host/include/uhd/utils/math.hpp | 12 | ||||
| -rw-r--r-- | host/include/uhd/utils/paths.hpp | 2 | 
18 files changed, 947 insertions, 17 deletions
diff --git a/host/include/uhd/config.hpp b/host/include/uhd/config.hpp index 7ecc4924a..8939cd773 100644 --- a/host/include/uhd/config.hpp +++ b/host/include/uhd/config.hpp @@ -1,5 +1,5 @@  // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2011,2014-2015 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 @@ -56,6 +56,13 @@ typedef ptrdiff_t ssize_t;      #define UHD_DEPRECATED     __declspec(deprecated)      #define UHD_ALIGNED(x)     __declspec(align(x))      #define UHD_UNUSED(x)      x +#elif defined(__MINGW32__) +    #define UHD_EXPORT         __declspec(dllexport) +    #define UHD_IMPORT         __declspec(dllimport) +    #define UHD_INLINE         inline +    #define UHD_DEPRECATED     __declspec(deprecated) +    #define UHD_ALIGNED(x)     __declspec(align(x)) +    #define UHD_UNUSED(x)      x __attribute__((unused))  #elif defined(__GNUG__) && __GNUG__ >= 4      #define UHD_EXPORT         __attribute__((visibility("default")))      #define UHD_IMPORT         __attribute__((visibility("default"))) diff --git a/host/include/uhd/convert.hpp b/host/include/uhd/convert.hpp index d740d80fb..e42123b20 100644 --- a/host/include/uhd/convert.hpp +++ b/host/include/uhd/convert.hpp @@ -63,12 +63,13 @@ namespace uhd{ namespace convert{      typedef int priority_type;      //! Identify a conversion routine in the registry -    struct id_type : boost::equality_comparable<id_type>{ +    struct UHD_API id_type : boost::equality_comparable<id_type>{          std::string input_format;          size_t num_inputs;          std::string output_format;          size_t num_outputs;          std::string to_pp_string(void) const; +        std::string to_string(void) const;      };      //! Implement equality_comparable interface diff --git a/host/include/uhd/transport/CMakeLists.txt b/host/include/uhd/transport/CMakeLists.txt index 2118674c6..623c179e9 100644 --- a/host/include/uhd/transport/CMakeLists.txt +++ b/host/include/uhd/transport/CMakeLists.txt @@ -1,5 +1,5 @@  # -# Copyright 2010-2013 Ettus Research LLC +# Copyright 2010-2014 Ettus Research LLC  #  # This program is free software: you can redistribute it and/or modify  # it under the terms of the GNU General Public License as published by @@ -15,11 +15,11 @@  # along with this program.  If not, see <http://www.gnu.org/licenses/>.  # -  UHD_INSTALL(FILES      bounded_buffer.hpp      bounded_buffer.ipp      buffer_pool.hpp +    chdr.hpp      if_addrs.hpp      udp_constants.hpp      udp_simple.hpp diff --git a/host/include/uhd/transport/chdr.hpp b/host/include/uhd/transport/chdr.hpp new file mode 100644 index 000000000..5e8cd58a9 --- /dev/null +++ b/host/include/uhd/transport/chdr.hpp @@ -0,0 +1,113 @@ +// +// Copyright 2014 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TRANSPORT_CHDR_HPP +#define INCLUDED_UHD_TRANSPORT_CHDR_HPP + +#include <uhd/transport/vrt_if_packet.hpp> + +namespace uhd{ namespace transport{ namespace vrt{ + +/*! \brief CVITA/CHDR related function + * + * See \ref rtp_chdr for details on the CVITA/CHDR protocol. + * + * All packers take the host format into account. Choose the _le functions + * if the transport uses little endian format (e.g. PCIe) and the _be + * functions if the transport uses big endian format (e.g. Ethernet). + * + * Note 1: All packers assume there to be enough space at the address + * provided by \p packet_buff. See also \ref vrt_pack_contract. + * + * Note 2: All these packers assume the following options without checking them: + * - `if_packet_info.link_type == LINK_TYPE_CHDR` + * - `if_packet_info.has_cid == false` + * - `if_packet_info.has_sid == true` + * - `if_packet_info.has_tsi == false` + * - `if_packet_info.has_tlr == false` + * This relaxes some of \ref vrt_pack_contract, but adds the additional + * constraint that the input data must be CHDR. + * + * In the unpacker, these values will be set accordingly. + */ +namespace chdr{ + +    //! The maximum number of 64-bit words in a CVITA header +    static const size_t max_if_hdr_words64 = 2; // CHDR + tsf (fractional timestamp) + +    /*! +     * Pack a CHDR header from metadata (big endian format). +     * +     * See \ref vrt_pack_contract, but `link_type` is assumed to be +     * `LINK_TYPE_CHDR`. +     * +     * \param packet_buff memory to write the packed vrt header +     * \param if_packet_info the if packet info (read/write) +     */ +    UHD_API void if_hdr_pack_be( +        boost::uint32_t *packet_buff, +        if_packet_info_t &if_packet_info +    ); + +    /*! +     * Unpack a CHDR header to metadata (big endian format). +     * +     * See \ref vrt_unpack_contract, but `link_type` is assumed to be +     * `LINK_TYPE_CHDR`. +     * +     * \param packet_buff memory to read the packed vrt header +     * \param if_packet_info the if packet info (read/write) +     */ +    UHD_API void if_hdr_unpack_be( +        const boost::uint32_t *packet_buff, +        if_packet_info_t &if_packet_info +    ); + +    /*! +     * Pack a CHDR header from metadata (little endian format). +     * +     * See \ref vrt_pack_contract, but `link_type` is assumed to be +     * `LINK_TYPE_CHDR`. +     * +     * \param packet_buff memory to write the packed vrt header +     * \param if_packet_info the if packet info (read/write) +     */ +    UHD_API void if_hdr_pack_le( +        boost::uint32_t *packet_buff, +        if_packet_info_t &if_packet_info +    ); + +    /*! +     * Unpack a CHDR header to metadata (little endian format). +     * +     * See \ref vrt_unpack_contract, but `link_type` is assumed to be +     * `LINK_TYPE_CHDR`. +     * +     * \param packet_buff memory to read the packed vrt header +     * \param if_packet_info the if packet info (read/write) +     */ +    UHD_API void if_hdr_unpack_le( +        const boost::uint32_t *packet_buff, +        if_packet_info_t &if_packet_info +    ); + +} //namespace chdr + +}}} //namespace uhd::transport::vrt + +#endif /* INCLUDED_UHD_TRANSPORT_CHDR_HPP */ + diff --git a/host/include/uhd/transport/nirio/nirio_driver_iface.h b/host/include/uhd/transport/nirio/nirio_driver_iface.h index 83afd816a..c562f0ca5 100644 --- a/host/include/uhd/transport/nirio/nirio_driver_iface.h +++ b/host/include/uhd/transport/nirio/nirio_driver_iface.h @@ -1,5 +1,5 @@  // -// Copyright 2013-2014 Ettus Research LLC +// Copyright 2013-2015 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 @@ -24,10 +24,14 @@  #include <uhd/transport/nirio/status.h>  #include <uhd/config.hpp>  #if defined(UHD_PLATFORM_WIN32) -    #include <Windows.h> -    #pragma warning(disable:4201)  // nonstandard extension used : nameless struct/union -        #include <WinIoCtl.h> -    #pragma warning(default:4201) +    #include <windows.h> +    #ifdef _MSC_VER +        #pragma warning(disable:4201)  // nonstandard extension used : nameless struct/union +    #endif +        #include <winioctl.h> +    #ifdef _MSC_VER +        #pragma warning(default:4201) +    #endif  #elif !defined(UHD_PLATFORM_LINUX)      #include <IOKit/IOKitLib.h>  #endif diff --git a/host/include/uhd/transport/nirio/nirio_fifo.h b/host/include/uhd/transport/nirio/nirio_fifo.h index c424275fc..5a2e29631 100644 --- a/host/include/uhd/transport/nirio/nirio_fifo.h +++ b/host/include/uhd/transport/nirio/nirio_fifo.h @@ -59,8 +59,8 @@ public:      inline const std::string& get_name() const { return _name; }      inline uint32_t get_channel() const { return _fifo_channel; } -    inline uint32_t get_direction() const { return _fifo_direction; } -    inline uint32_t get_scalar_type() const { return _datatype_info.scalar_type; } +    inline fifo_direction_t get_direction() const { return _fifo_direction; } +    inline nirio_scalar_type_t get_scalar_type() const { return _datatype_info.scalar_type; }      nirio_status start(); diff --git a/host/include/uhd/transport/usb_device_handle.hpp b/host/include/uhd/transport/usb_device_handle.hpp index fdea9e2be..bf122f549 100644 --- a/host/include/uhd/transport/usb_device_handle.hpp +++ b/host/include/uhd/transport/usb_device_handle.hpp @@ -41,6 +41,7 @@ namespace uhd { namespace transport {  class UHD_API usb_device_handle : boost::noncopyable {  public:      typedef boost::shared_ptr<usb_device_handle> sptr; +    typedef std::pair<boost::uint16_t, boost::uint16_t> vid_pid_pair_t;      /*!       * Return the device's serial number @@ -83,6 +84,8 @@ public:       * \return a vector of USB device handles that match vid and pid       */      static std::vector<usb_device_handle::sptr> get_device_list(boost::uint16_t vid, boost::uint16_t pid); +    static std::vector<usb_device_handle::sptr> get_device_list(const std::vector<usb_device_handle::vid_pid_pair_t>& vid_pid_pair_list); +  }; //namespace usb diff --git a/host/include/uhd/transport/vrt_if_packet.hpp b/host/include/uhd/transport/vrt_if_packet.hpp index 362531567..1e54607c1 100644 --- a/host/include/uhd/transport/vrt_if_packet.hpp +++ b/host/include/uhd/transport/vrt_if_packet.hpp @@ -1,5 +1,5 @@  // -// Copyright 2010-2013 Ettus Research LLC +// Copyright 2010-2014 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by @@ -52,9 +52,18 @@ namespace vrt{          //packet type          enum packet_type_t          { +            // VRT language:              PACKET_TYPE_DATA      = 0x0,              PACKET_TYPE_IF_EXT    = 0x1, -            PACKET_TYPE_CONTEXT   = 0x2  //extension context: has_sid = true +            PACKET_TYPE_CONTEXT   = 0x2, //extension context: has_sid = true + +            // CVITA language: +            //PACKET_TYPE_DATA      = 0x0, // Data +            PACKET_TYPE_FC        = 0x1, // Flow control +            PACKET_TYPE_ACK       = 0x1, // Flow control (ack) +            PACKET_TYPE_CMD       = 0x2, // Command +            PACKET_TYPE_RESP      = 0x3, // Command response +            PACKET_TYPE_ERROR     = 0x3  // Command response: Error (the EOB bit is raised in this case)          } packet_type;          //size fields @@ -65,18 +74,46 @@ namespace vrt{          //header fields          size_t packet_count; +        //! Asserted for start- or end-of-burst          bool sob, eob; +        //! This is asserted for command responses that are errors (CHDR only) +        bool error;          //optional fields +        //! Stream ID (SID). See uhd::sid_t          bool has_sid; boost::uint32_t sid; +        //! Class ID.          bool has_cid; boost::uint64_t cid; +        //! Integer timestamp          bool has_tsi; boost::uint32_t tsi; +        //! Fractional timestamp          bool has_tsf; boost::uint64_t tsf; +        //! Trailer          bool has_tlr; boost::uint32_t tlr;      };      /*!       * Pack a vrt header from metadata (big endian format). +     * +     * \section vrt_pack_contract Packing contract +     * +     * \subsection Requirements: +     * - packet_buff points to a valid address space with enough space to write +     *   the entire buffer, regardless of its length. At the very least, it must +     *   be able to hold an entire header. +     * - `if_packet_info` has the following members set to correct values: +     *   - `has_*` members all set accordingly +     *   - For every true `has_*` member, the corresponding variable holds a valid +     *     value (e.g. if `has_sid` is true, `sid` contains a valid SID) +     *   - `num_payload_bytes` and `num_payload_words32` are both set to the correct values +     * +     * \subsection Result: +     * - `packet_buff` now points to a valid header that can be sent over the transport +     *   without further modification +     * - The following members on `if_packet_info` are set: +     *   - `num_header_words32` +     *   - `num_packet_words32` +     *       * \param packet_buff memory to write the packed vrt header       * \param if_packet_info the if packet info (read/write)       */ @@ -87,6 +124,34 @@ namespace vrt{      /*!       * Unpack a vrt header to metadata (big endian format). +     * +     * \section vrt_unpack_contract Unpacking contract +     * +     * \subsection Requirements +     * - `packet_buff` points to a readable address space with a +     *   CHDR packet, starting at the header. `packet_buff[0]` *must* always +     *   point to a valid first word of the header. This implies that num_packet_words32 +     *   must be at least 1. +     * - `if_packet_info` has the following members set to correct values: +     *   - `num_packet_words32`. This means all values `packet_buff[0]` +     *     through `packet_buff[if_packet_info.num_packet_words32-1]` are +     *     readable words from this packet. +     *   - `link_type` +     * +     * \subsection Result +     * - `if_packet_info` now has the following values set to correct values: +     *   - `packet_type` +     *   - `num_payload_bytes` +     *   - `num_payload_words32` +     *   - `num_header_words32` +     *   - `has_*` +     *   - `sob`, `eob`, `error`, `cid`, `sid` (if applicable) +     *   - `tsf`, `tsi` (if applicable) +     * +     * \subsection Exceptions +     * - If the header is invalid, but the requirements are still met, +     *   will throw a uhd::value_error. +     *       * \param packet_buff memory to read the packed vrt header       * \param if_packet_info the if packet info (read/write)       */ @@ -97,6 +162,9 @@ namespace vrt{      /*!       * Pack a vrt header from metadata (little endian format). +     * +     * See \ref vrt_pack_contract. +     *       * \param packet_buff memory to write the packed vrt header       * \param if_packet_info the if packet info (read/write)       */ @@ -107,6 +175,9 @@ namespace vrt{      /*!       * Unpack a vrt header to metadata (little endian format). +     * +     * See \ref vrt_unpack_contract. +     *       * \param packet_buff memory to read the packed vrt header       * \param if_packet_info the if packet info (read/write)       */ @@ -124,6 +195,7 @@ namespace vrt{          num_packet_words32(0),          packet_count(0),          sob(false), eob(false), +        error(false),          has_sid(false), sid(0),          has_cid(false), cid(0),          has_tsi(false), tsi(0), diff --git a/host/include/uhd/types/CMakeLists.txt b/host/include/uhd/types/CMakeLists.txt index 8bb1de381..2a25df35f 100644 --- a/host/include/uhd/types/CMakeLists.txt +++ b/host/include/uhd/types/CMakeLists.txt @@ -17,6 +17,7 @@  UHD_INSTALL(FILES +    byte_vector.hpp      clock_config.hpp      device_addr.hpp      dict.ipp @@ -31,11 +32,13 @@ UHD_INSTALL(FILES      ref_vector.hpp      sensors.hpp      serial.hpp +    sid.hpp      stream_cmd.hpp      time_spec.hpp      tune_request.hpp      tune_result.hpp      wb_iface.hpp +    filters.hpp      DESTINATION ${INCLUDE_DIR}/uhd/types      COMPONENT headers  ) diff --git a/host/include/uhd/types/byte_vector.hpp b/host/include/uhd/types/byte_vector.hpp new file mode 100644 index 000000000..b7637fb5d --- /dev/null +++ b/host/include/uhd/types/byte_vector.hpp @@ -0,0 +1,48 @@ +// +// Copyright 2015 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_TYPES_BYTE_VECTOR_HPP +#define INCLUDED_UHD_TYPES_BYTE_VECTOR_HPP + +#include <algorithm> +#include <string> +#include <vector> + +#include <boost/assign.hpp> +#include <boost/cstdint.hpp> + +#include <uhd/config.hpp> + +namespace uhd{ + +    //! Byte vector used for I2C data passing and EEPROM parsing. +    typedef std::vector<boost::uint8_t> byte_vector_t; + +    template<typename RangeSrc, typename RangeDst> UHD_INLINE +    void byte_copy(const RangeSrc &src, RangeDst &dst){ +        std::copy(boost::begin(src), boost::end(src), boost::begin(dst)); +    } + +    //! Create a string from a byte vector, terminate when invalid ASCII encountered +    UHD_API std::string bytes_to_string(const byte_vector_t &bytes); + +    //! Create a byte vector from a string, end at null terminator or max length +    UHD_API byte_vector_t string_to_bytes(const std::string &str, size_t max_length); + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_BYTE_VECTOR_HPP */ diff --git a/host/include/uhd/types/dict.hpp b/host/include/uhd/types/dict.hpp index 97fa8f09c..51e3e1814 100644 --- a/host/include/uhd/types/dict.hpp +++ b/host/include/uhd/types/dict.hpp @@ -1,5 +1,5 @@  // -// Copyright 2010-2011 Ettus Research LLC +// Copyright 2010-2011,2015 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 @@ -117,6 +117,23 @@ namespace uhd{           */          Val pop(const Key &key); +        /*! Update this dictionary with values from another. +         * +         * Basically, this copies all the key/value pairs from \p new_dict +         * into this dict. When the key is already present in the current +         * dict, it either overwrites the current value (if \p fail_on_conflict +         * is false) or it throws (if \p fail_on_conflict is true *and* the +         * values differ). +         * +         * With the exception of \p fail_on_conflict, this behaves analogously +         * to Python's dict.update() method. +         * +         * \param new_args The arguments to copy. +         * \param fail_on_conflict If true, throws. +         * \throws uhd::value_error +         */ +        void update(const dict<Key, Val> &new_dict, bool fail_on_conflict=true); +      private:          typedef std::pair<Key, Val> pair_t;          std::list<pair_t> _map; //private container diff --git a/host/include/uhd/types/dict.ipp b/host/include/uhd/types/dict.ipp index 5e9cf97ad..5fd4b536e 100644 --- a/host/include/uhd/types/dict.ipp +++ b/host/include/uhd/types/dict.ipp @@ -135,6 +135,20 @@ namespace uhd{          throw key_not_found<Key, Val>(key);      } +    template <typename Key, typename Val> +    void dict<Key, Val>::update(const dict<Key, Val> &new_dict, bool fail_on_conflict) +    { +        BOOST_FOREACH(const Key &key, new_dict.keys()) { +            if (fail_on_conflict and has_key(key) and get(key) != new_dict[key]) { +                throw uhd::value_error(str( +                    boost::format("Option merge conflict: %s:%s != %s:%s") +                    % key % get(key) % key % new_dict[key] +                )); +            } +            set(key, new_dict[key]); +        } +    } +  } //namespace uhd  #endif /* INCLUDED_UHD_TYPES_DICT_IPP */ diff --git a/host/include/uhd/types/direction.hpp b/host/include/uhd/types/direction.hpp index 0f257de44..59ee9b55f 100644 --- a/host/include/uhd/types/direction.hpp +++ b/host/include/uhd/types/direction.hpp @@ -1,5 +1,5 @@  // -// Copyright 2015 Ettus Research LLC +// Copyright 2014-2015 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 diff --git a/host/include/uhd/types/filters.hpp b/host/include/uhd/types/filters.hpp new file mode 100644 index 000000000..976ae233d --- /dev/null +++ b/host/include/uhd/types/filters.hpp @@ -0,0 +1,286 @@ +// +// Copyright 2015 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_TYPES_FILTERS_HPP +#define INCLUDED_UHD_TYPES_FILTERS_HPP + +#include <uhd/config.hpp> +#include <uhd/utils/log.hpp> +#include <uhd/utils/msg.hpp> +#include <boost/cstdint.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/scoped_array.hpp> +#include <string> +#include <vector> +#include <iostream> +#include <ostream> +#include <sstream> + +namespace uhd{ + +    class UHD_API filter_info_base +    { +    public: +        typedef boost::shared_ptr<filter_info_base> sptr; +        enum filter_type +        { +            ANALOG_LOW_PASS, +            ANALOG_BAND_PASS, +            DIGITAL_I16, +            DIGITAL_FIR_I16 +        }; + +        filter_info_base( +            filter_type type, +            bool bypass, +            size_t position_index +        ): +            _type(type), _bypass(bypass), +            _position_index(position_index) +        { +            //NOP +        } + +        inline virtual bool is_bypassed() +        { +            return _bypass; +        } + +        inline filter_type get_type() +        { +            return _type; +        } + +        virtual ~filter_info_base() +        { +            //NOP +        } + +        virtual std::string to_pp_string(); + +    protected: +        filter_type _type; +        bool _bypass; +        size_t _position_index; + +    }; + +    UHD_API std::ostream& operator<<(std::ostream& os, filter_info_base& f); + +    class UHD_API analog_filter_base : public filter_info_base +    { +        std::string _analog_type; +        public: +            typedef boost::shared_ptr<analog_filter_base> sptr; +            analog_filter_base( +                filter_type type, +                bool bypass, +                size_t position_index, +                const std::string& analog_type +            ): +                filter_info_base(type, bypass, position_index), +                _analog_type(analog_type) +            { +                //NOP +            } + +            inline const std::string& get_analog_type() +            { +                return _analog_type; +            } + +            virtual std::string to_pp_string(); +    }; + +    class UHD_API analog_filter_lp : public analog_filter_base +    { +        double _cutoff; +        double _rolloff; + +    public: +        typedef boost::shared_ptr<analog_filter_lp> sptr; +        analog_filter_lp( +            filter_type type, +            bool bypass, +            size_t position_index, +            const std::string& analog_type, +            double cutoff, +            double rolloff +        ): +            analog_filter_base(type, bypass, position_index, analog_type), +            _cutoff(cutoff), +            _rolloff(rolloff) +        { +            //NOP +        } + +        inline double get_cutoff() +        { +            return _cutoff; +        } + +        inline double get_rolloff() +        { +            return _cutoff; +        } + +        inline void set_cutoff(const double cutoff) +        { +            _cutoff = cutoff; +        } + +        virtual std::string to_pp_string(); +    }; + +    template<typename tap_t> +    class UHD_API digital_filter_base : public filter_info_base +    { +    protected: +        double _rate; +        boost::uint32_t _interpolation; +        boost::uint32_t _decimation; +        tap_t _tap_full_scale; +        boost::uint32_t _max_num_taps; +        std::vector<tap_t> _taps; + +    public: +        typedef boost::shared_ptr<digital_filter_base> sptr; +        digital_filter_base( +            filter_type type, +            bool bypass, +            size_t position_index, +            double rate, +            size_t interpolation, +            size_t decimation, +            double tap_full_scale, +            size_t max_num_taps, +            const std::vector<tap_t>& taps +        ): +            filter_info_base(type, bypass, position_index), +            _rate(rate), +            _interpolation(interpolation), +            _decimation(decimation), +            _tap_full_scale(tap_full_scale), +            _max_num_taps(max_num_taps), +            _taps(taps) +        { +            //NOP +        } + +        inline double get_output_rate() +        { +            return (_bypass ? _rate : (_rate / _decimation * _interpolation)); +        } + +        inline double get_input_rate() +        { +            return _rate; +        } + +        inline double get_interpolation() +        { +            return _interpolation; +        } + +        inline double get_decimation() +        { +            return _decimation; +        } + +        inline double get_tap_full_scale() +        { +            return _tap_full_scale; +        } + +        inline std::vector<tap_t>& get_taps() +        { +            return _taps; +        } + +        virtual std::string to_pp_string() +        { +            std::ostringstream os; +            os<<filter_info_base::to_pp_string()<< +            "\t[digital_filter_base]"<<std::endl<< +            "\tinput rate: "<<_rate<<std::endl<< +            "\tinterpolation: "<<_interpolation<<std::endl<< +            "\tdecimation: "<<_decimation<<std::endl<< +            "\tfull-scale: "<<_tap_full_scale<<std::endl<< +            "\tmax num taps: "<<_max_num_taps<<std::endl<< +            "\ttaps: "<<std::endl; + +            os<<"\t\t"; +            for(size_t i = 0; i < _taps.size(); i++) +            { +                os<<"(tap "<<i<<": "<<_taps[i]<<")"; +                if( ((i%10) == 0) && (i != 0)) +                { +                    os<<std::endl<<"\t\t"; +                } +            } +            os<<std::endl; +            return std::string(os.str()); +        } + +    }; + +    template<typename tap_t> +    class UHD_API digital_filter_fir : public digital_filter_base<tap_t> +    { +    public: +        typedef boost::shared_ptr<digital_filter_fir<tap_t> > sptr; + +        digital_filter_fir( +            filter_info_base::filter_type type, +            bool bypass, size_t position_index, +            double rate, +            size_t interpolation, +            size_t decimation, +            size_t tap_bit_width, +            size_t max_num_taps, +            const std::vector<tap_t>& taps +        ): +            digital_filter_base<tap_t>(type, bypass, position_index, rate, interpolation, decimation, tap_bit_width, max_num_taps, taps) +        { +            //NOP +        } + +        void set_taps(const std::vector<tap_t>& taps) +        { +            std::size_t num_taps = taps.size(); +            if(num_taps < this->_max_num_taps){ +                UHD_MSG(warning) << "digital_filter_fir::set_taps not enough coefficients. Appending zeros"; +                std::vector<tap_t> coeffs; +                for (size_t i = 0; i < this->_max_num_taps; i++) +                { +                    if(i < num_taps) +                    { +                        coeffs.push_back(taps[i]); +                    } else { +                        coeffs.push_back(0); +                    } +                } +                this->_taps = coeffs; +            } else { +                this->_taps = taps; +            } +        } +    }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_FILTERS_HPP */ diff --git a/host/include/uhd/types/sid.hpp b/host/include/uhd/types/sid.hpp new file mode 100644 index 000000000..95034c7a5 --- /dev/null +++ b/host/include/uhd/types/sid.hpp @@ -0,0 +1,238 @@ +// +// Copyright 2014 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TYPES_SID_HPP +#define INCLUDED_UHD_TYPES_SID_HPP + +#include <uhd/config.hpp> +#include <boost/cstdint.hpp> +#include <boost/shared_ptr.hpp> +#include <iostream> + +namespace uhd { +    /*! +     * \brief Represents a stream ID (SID). +     * +     * A stream ID (SID) is an identifier for data. +     * It is a 32-Bit value which consistst of 16 Bits +     * for the source address and 16 Bits for the destination +     * address. +     * Every address is split into two parts: The _address_, which +     * identifies the device used, and the _endpoint_, which identifies +     * a specific object inside the given device (e.g., a block). +     * *Note:* In the case where there are several crossbars on a single +     * device, each crossbar gets its own address. +     * Both address and endpoint are 8 bits in length. If a 16-bit address +     * is required, we use the combination of the 8-bit address and the 8-bit +     * endpoint. +     * +     * \section sid_str_repr String Representation +     * +     * The string representation of a SID is of the form +     * +     *     2.3>0.6 +     * +     * The '>' symbol shows the direction, so in this case, +     * data is flowing from address 2.3 to 0.6. +     * +     * As a convention, ':' is used instead of '.' when giving the +     * SID in hexadecimal numbers, and two characters are used for each +     * address part. As an example, the following two SIDs are identical: +     * +     *     2.3>0.16 (decimal) +     *     02:03>00:10 (hexadecimal) +     * +     * The format is: +     *     SRC_ADDRESS.SRC_ENDPOINT>DST_ADDRESS.DST_ENDPOINT +     * +     * +     * \section sid_block_ports Block Ports +     * +     * In the special case where a block on a crossbar is addressed, the +     * endpoint is further split up into two parts of four bits each: The +     * first four bits specify the port number on the crossbar, whereas the +     * lower four bits represent the *block port*. As an example, consider +     * the following SID, given in hexadecimal: +     * +     *    00:10>02:A1 +     * +     * In this example, assume data is flowing from the host computer to an +     * X300. The crossbar address is 02. The endpoint is A1, which means we +     * are accessing a block on crossbar port A (the tenth port), and are addressing +     * block port 1. +     * +     */ +    class UHD_API sid_t +    { +    public: +        //! Create an unset SID +        sid_t(); +        //! Create a sid_t object from a 32-Bit SID value +        sid_t(boost::uint32_t sid); +        //! Create a sid_t object from its four components +        sid_t(boost::uint8_t src_addr, boost::uint8_t src_ep, boost::uint8_t dst_addr, boost::uint8_t dst_ep); +        //! Convert a string representation of a SID into its numerical representation +        sid_t(const std::string &); + +        //! Return a decimal string representation of the SID. +        std::string to_pp_string() const; +        //! Return a hexadecimal string representation of the SID. +        std::string to_pp_string_hex() const; + +        //! Returns true if this actually holds a valid SID +        bool is_set() const { return _set; }; + +        // Getters +        // +        //! Alias for get_sid() +        UHD_INLINE boost::uint32_t get() const { return get_sid(); }; +        //! Returns a 32-Bit representation of the SID if set, or zero otherwise. +        UHD_INLINE boost::uint32_t get_sid() const { return _set ? _sid : 0; }; +        //! Return the 16-bit source address of this SID +        UHD_INLINE boost::uint32_t get_src() const { +            return (_sid >> 16) & 0xFFFF; +        } +        //! Return the 16-bit destination address of this SID +        UHD_INLINE boost::uint32_t get_dst() const { +            return _sid & 0xFFFF; +        } +        //! Return 8-bit address of the source +        UHD_INLINE boost::uint32_t get_src_addr() const { +            return (get_src() >> 8) & 0xFF; +        } +        //! Return endpoint of the source +        UHD_INLINE boost::uint32_t get_src_endpoint() const { +            return get_src() & 0xFF; +        } +        //! Return crossbar port of the source +        UHD_INLINE boost::uint32_t get_src_xbarport() const { +            return (get_src_endpoint() >> 4) & 0xF; +        } +        //! Return block port of the source +        UHD_INLINE boost::uint32_t get_src_blockport() const { +            return (get_src_endpoint()) & 0xF; +        } +        //! Return 8-bit address of the destination +        UHD_INLINE boost::uint32_t get_dst_addr() const { +            return (get_dst() >> 8) & 0xFF; +        } +        //! Return endpoint of the destination +        UHD_INLINE boost::uint32_t get_dst_endpoint() const { +            return get_dst() & 0xFF; +        } +        //! Return crossbar port of the source +        UHD_INLINE boost::uint32_t get_dst_xbarport() const { +            return (get_dst_endpoint() >> 4) & 0xF; +        } +        //! Return block port of the source +        UHD_INLINE boost::uint32_t get_dst_blockport() const { +            return (get_dst_endpoint()) & 0xF; +        } + +        // Setters + +        //! Alias for set_sid() +        void set(boost::uint32_t new_sid) { set_sid(new_sid); }; +        //! Convert a string representation of a SID into a numerical one +        // Throws uhd::value_error if the string is not a valid SID +        // representation. +        void set_from_str(const std::string &); +        void set_sid(boost::uint32_t new_sid); +        //! Set the source address of this SID +        //  (the first 16 Bits) +        void set_src(boost::uint32_t new_addr); +        //! Set the destination address of this SID +        //  (the last 16 Bits) +        void set_dst(boost::uint32_t new_addr); +        void set_src_addr(boost::uint32_t new_addr); +        void set_src_endpoint(boost::uint32_t new_addr); +        void set_dst_addr(boost::uint32_t new_addr); +        void set_dst_endpoint(boost::uint32_t new_addr); +        void set_dst_xbarport(boost::uint32_t new_xbarport); +        void set_dst_blockport(boost::uint32_t new_blockport); + +        // Manipulators + +        //! Swaps dst and src address and returns the new SID. +        sid_t reversed(); + +        //! Swaps dst and src in-place. +        void reverse(); + +        // Overloaded operators + +        sid_t operator = (boost::uint32_t new_sid) { +            set_sid(new_sid); +            return *this; +        } + +        sid_t operator = (sid_t &sid) { +            set_sid(sid.get_sid()); +            return *this; +        } + +        sid_t operator = (const std::string &sid_str) { +            set_from_str(sid_str); +            return *this; +        } + +        bool operator == (const sid_t &sid) const { +            return (not _set and not sid.is_set()) or (_sid == sid.get_sid()); +        } + +        bool operator == (boost::uint32_t sid) const { +            return _set and _sid == sid; +        } + +        bool operator == (const std::string &sid_str) const { +            sid_t rhs(sid_str); +            return *this == rhs; +        } + +        // overloaded type casts are tricky, but for now we'll need them +        // for backward compatibility. consider them deprecated. + +        //! If the SID is not set, always returns zero. +        //  Use is_set() to check if the return value is valid. +        operator boost::uint32_t() const { +            return get(); +        } + +        operator bool() const { +            return _set; +        } + +    private: +        boost::uint32_t _sid; +        bool _set; +    }; + +    //! Stream output operator. Honors std::ios::hex. +    UHD_INLINE std::ostream& operator<< (std::ostream& out, const sid_t &sid) { +        std::ios_base::fmtflags ff = out.flags(); +        if (ff & std::ios::hex) { +            out << sid.to_pp_string_hex(); +        } else { +            out << sid.to_pp_string(); +        } +        return out; +    } + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_SID_HPP */ +// vim: sw=4 et: diff --git a/host/include/uhd/usrp/multi_usrp.hpp b/host/include/uhd/usrp/multi_usrp.hpp index 6fd22ff23..f0bb6d8d3 100644 --- a/host/include/uhd/usrp/multi_usrp.hpp +++ b/host/include/uhd/usrp/multi_usrp.hpp @@ -22,10 +22,12 @@  #define UHD_USRP_MULTI_USRP_REF_SOURCES_API  #define UHD_USRP_MULTI_USRP_GET_RATES_API  #define UHD_USRP_MULTI_USRP_FRONTEND_CAL_API +#define UHD_USRP_MULTI_USRP_FRONTEND_IQ_AUTO_API  #define UHD_USRP_MULTI_USRP_COMMAND_TIME_API  #define UHD_USRP_MULTI_USRP_BW_RANGE_API  #define UHD_USRP_MULTI_USRP_USER_REGS_API  #define UHD_USRP_MULTI_USRP_GET_USRP_INFO_API +#define UHD_USRP_MULTI_USRP_NORMALIZED_GAIN  #include <uhd/config.hpp>  #include <uhd/device.hpp> @@ -35,6 +37,7 @@  #include <uhd/types/tune_request.hpp>  #include <uhd/types/tune_result.hpp>  #include <uhd/types/sensors.hpp> +#include <uhd/types/filters.hpp>  #include <uhd/usrp/subdev_spec.hpp>  #include <uhd/usrp/dboard_iface.hpp>  #include <boost/shared_ptr.hpp> @@ -155,6 +158,11 @@ public:       * If the specified rate is not available, this method will throw.       * On other devices, this method notifies the software of the rate,       * but requires the the user has made the necessary hardware change. +     * +     * If the device has an 'auto clock rate' setting (e.g. B200, see also +     * \ref b200_auto_mcr), this will get disabled and the clock rate will be +     * fixed to \p rate. +     *       * \param rate the new master clock rate in Hz       * \param mboard the motherboard index 0 to M-1       */ @@ -490,6 +498,34 @@ public:      }      /*! +     * Set the normalized RX gain value. +     * +     * The normalized gain is a value in [0, 1], where 0 is the +     * smallest gain value available, and 1 is the largest, independent +     * of the device. In between, gains are linearly interpolated. +     * +     * Check the individual device manual for notes on the gain range. +     * +     * Note that it is not possible to specify a gain name for +     * this function, it will always set the overall gain. +     * +     * \param gain the normalized gain value +     * \param chan the channel index 0 to N-1 +     * \throws A uhd::runtime_error if the gain value is outside [0, 1]. +     */ +    virtual void set_normalized_rx_gain(double gain, size_t chan = 0) = 0; + +    /*! +     * Enable or disable the RX AGC module. +     * Once this module is enabled manual gain settings will be ignored. +     * The AGC will start in a default configuration which should be good for most use cases. +     * Device specific configuration parameters can be found in the property tree. +     * \param on Enable or Disable the AGC +     * \param chan the channel index 0 to N-1 +     */ +    virtual void set_rx_agc(bool enable, size_t chan = 0) = 0; + +    /*!       * Get the RX gain value for the specified gain element.       * For an empty name, sum across all gain elements.       * \param name the name of the gain element @@ -504,6 +540,19 @@ public:      }      /*! +     * Return the normalized RX gain value. +     * +     * See set_normalized_rx_gain() for a discussion of normalized +     * gains. +     * +     * \param gain the normalized gain value +     * \param chan the channel index 0 to N-1 +     * \returns The normalized gain (in [0, 1]) +     * \throws A uhd::runtime_error if the gain value is outside [0, 1]. +     */ +    virtual double get_normalized_rx_gain(size_t chan = 0) = 0; + +    /*!       * Get the RX gain range for the specified gain element.       * For an empty name, calculate the overall gain range.       * \param name the name of the gain element @@ -615,6 +664,14 @@ public:      virtual void set_rx_dc_offset(const std::complex<double> &offset, size_t chan = ALL_CHANS) = 0;      /*! +     * Enable/disable the automatic IQ imbalance correction. +     * +     * \param enb true to enable automatic IQ balance correction +     * \param chan the channel index 0 to N-1 +     */ +    virtual void set_rx_iq_balance(const bool enb, size_t chan) = 0; + +    /*!       * Set the RX frontend IQ imbalance correction.       * Use this to adjust the magnitude and phase of I and Q.       * @@ -728,6 +785,18 @@ public:      }      /*! +     * Set the normalized TX gain value. +     * +     * See set_normalized_rx_gain() for a discussion on normalized +     * gains. +     * +     * \param gain the normalized gain value +     * \param chan the channel index 0 to N-1 +     * \throws A uhd::runtime_error if the gain value is outside [0, 1]. +     */ +    virtual void set_normalized_tx_gain(double gain, size_t chan = 0) = 0; + +    /*!       * Get the TX gain value for the specified gain element.       * For an empty name, sum across all gain elements.       * \param name the name of the gain element @@ -742,6 +811,19 @@ public:      }      /*! +     * Return the normalized TX gain value. +     * +     * See set_normalized_rx_gain() for a discussion of normalized +     * gains. +     * +     * \param gain the normalized gain value +     * \param chan the channel index 0 to N-1 +     * \returns The normalized gain (in [0, 1]) +     * \throws A uhd::runtime_error if the gain value is outside [0, 1]. +     */ +    virtual double get_normalized_tx_gain(size_t chan = 0) = 0; + +    /*!       * Get the TX gain range for the specified gain element.       * For an empty name, calculate the overall gain range.       * \param name the name of the gain element @@ -893,6 +975,38 @@ public:       */      virtual boost::uint32_t get_gpio_attr(const std::string &bank, const std::string &attr, const size_t mboard = 0) = 0; +    /******************************************************************* +     * Filter API methods +     ******************************************************************/ + +    /*! +     * Enumerate the available filters in the signal path. +     * \param search_mask +     * \parblock +     * Select only certain filter names by specifying this search mask. +     * +     * E.g. if search mask is set to "rx_frontends/A" only filter names including that string will be returned. +     * \endparblock +     * \return a vector of strings representing the selected filter names. +     */ +    virtual std::vector<std::string> get_filter_names(const std::string &search_mask = "") = 0; + +    /*! +     * Return the filter object for the given name. +     * \param path the name of the filter as returned from get_filter_names(). +     * \return a filter_info_base::sptr. +     */ +    virtual filter_info_base::sptr get_filter(const std::string &path) = 0; + +    /*! +     * Write back a filter obtained by get_filter() to the signal path. +     * This filter can be a modified version of the originally returned one. +     * The information about Rx or Tx is contained in the path parameter. +     * \param path the name of the filter as returned from get_filter_names(). +     * \param filter the filter_info_base::sptr of the filter object to be written +     */ +    virtual void set_filter(const std::string &path, filter_info_base::sptr filter) = 0; +  };  }} diff --git a/host/include/uhd/utils/math.hpp b/host/include/uhd/utils/math.hpp index 4f88494d6..46a1cf7e4 100644 --- a/host/include/uhd/utils/math.hpp +++ b/host/include/uhd/utils/math.hpp @@ -18,11 +18,11 @@  #ifndef INCLUDED_UHD_UTILS_MATH_HPP  #define INCLUDED_UHD_UTILS_MATH_HPP +#include <cmath>  #include <uhd/config.hpp>  #include <boost/cstdint.hpp>  #include <boost/numeric/conversion/bounds.hpp> -  namespace uhd {  /*! @@ -237,6 +237,16 @@ namespace fp_compare {                  == fp_compare::fp_compare_delta<double>(rhs, FREQ_COMPARISON_DELTA_HZ));      } +    //! Portable log2() +    template <typename float_t> UHD_INLINE +    float_t log2(float_t x) +    { +        // C++11 defines std::log2(), when that's universally supported +        // we can switch over. +        return std::log(x) / std::log(float_t(2)); +    } + +  } // namespace math  } // namespace uhd diff --git a/host/include/uhd/utils/paths.hpp b/host/include/uhd/utils/paths.hpp index 8edb87546..aa31fd5a2 100644 --- a/host/include/uhd/utils/paths.hpp +++ b/host/include/uhd/utils/paths.hpp @@ -87,7 +87,7 @@ namespace uhd {       * The error string will include the full path to the utility to run.       * \return the message suggesting the use of the named utility.       */ -    UHD_API std::string print_utility_error(std::string name); +    UHD_API std::string print_utility_error(const std::string &name, const std::string &args="");  } //namespace uhd  #endif /* INCLUDED_UHD_UTILS_PATHS_HPP */  | 
