aboutsummaryrefslogtreecommitdiffstats
path: root/host/include
diff options
context:
space:
mode:
Diffstat (limited to 'host/include')
-rw-r--r--host/include/uhd/config.hpp9
-rw-r--r--host/include/uhd/convert.hpp3
-rw-r--r--host/include/uhd/exception.hpp8
-rw-r--r--host/include/uhd/image_loader.hpp89
-rw-r--r--host/include/uhd/transport/CMakeLists.txt4
-rw-r--r--host/include/uhd/transport/chdr.hpp113
-rw-r--r--host/include/uhd/transport/nirio/nirio_driver_iface.h14
-rw-r--r--host/include/uhd/transport/nirio/nirio_fifo.h4
-rw-r--r--host/include/uhd/transport/nirio/nirio_quirks.h4
-rw-r--r--host/include/uhd/transport/tcp_zero_copy.hpp4
-rw-r--r--host/include/uhd/transport/usb_device_handle.hpp3
-rw-r--r--host/include/uhd/transport/vrt_if_packet.hpp76
-rw-r--r--host/include/uhd/transport/zero_copy.hpp2
-rw-r--r--host/include/uhd/types/CMakeLists.txt3
-rw-r--r--host/include/uhd/types/byte_vector.hpp48
-rw-r--r--host/include/uhd/types/dict.hpp19
-rw-r--r--host/include/uhd/types/dict.ipp14
-rw-r--r--host/include/uhd/types/direction.hpp2
-rw-r--r--host/include/uhd/types/filters.hpp286
-rw-r--r--host/include/uhd/types/sid.hpp238
-rw-r--r--host/include/uhd/usrp/multi_usrp.hpp113
-rw-r--r--host/include/uhd/usrp_clock/CMakeLists.txt4
-rw-r--r--host/include/uhd/utils/math.hpp12
-rw-r--r--host/include/uhd/utils/paths.hpp2
-rw-r--r--host/include/uhd/utils/soft_register.hpp312
25 files changed, 1361 insertions, 25 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/exception.hpp b/host/include/uhd/exception.hpp
index 69e902fd5..a21106166 100644
--- a/host/include/uhd/exception.hpp
+++ b/host/include/uhd/exception.hpp
@@ -98,6 +98,14 @@ namespace uhd{
virtual void dynamic_throw(void) const;
};
+ struct UHD_API usb_error : runtime_error{
+ int _code;
+ usb_error(int code, const std::string &what);
+ virtual unsigned code(void) const { return _code; };
+ virtual usb_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
struct UHD_API not_implemented_error : runtime_error{
not_implemented_error(const std::string &what);
virtual unsigned code(void) const;
diff --git a/host/include/uhd/image_loader.hpp b/host/include/uhd/image_loader.hpp
new file mode 100644
index 000000000..8124e7dea
--- /dev/null
+++ b/host/include/uhd/image_loader.hpp
@@ -0,0 +1,89 @@
+//
+// 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
+// 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_IMAGE_LOADER_HPP
+#define INCLUDED_UHD_IMAGE_LOADER_HPP
+
+#include <string>
+
+#include <boost/function.hpp>
+
+#include <uhd/config.hpp>
+#include <uhd/types/device_addr.hpp>
+
+namespace uhd{
+
+class UHD_API image_loader : boost::noncopyable{
+
+public:
+
+ typedef struct{
+ uhd::device_addr_t args;
+ bool load_firmware;
+ bool load_fpga;
+ std::string firmware_path;
+ std::string fpga_path;
+ } image_loader_args_t;
+
+ //! Signature of an image loading function
+ /*!
+ * This is the function signature for an image loading function.
+ * See the declaration of load() for the meaning of these arguments.
+ *
+ * This function must return true upon the end of a successful image load
+ * or false if no applicable device was found. It may only throw a runtime
+ * error under one of two conditions:
+ *
+ * * The function has already engaged with a specific device and
+ * something goes wrong.
+ * * The user gives arguments that unambiguously lead to a specific
+ * device and expect the default image(s) to be loaded, but the specific
+ * model of the device cannot be determined beyond a category.
+ */
+ typedef boost::function<bool(const image_loader_args_t &)> loader_fcn_t;
+
+ //! Register an image loader
+ /*!
+ * \param device_type the "type=foo" value given in an --args option
+ * \param loader_fcn the loader function for the given device
+ * \param recovery_instructions instructions on how to restore a device
+ */
+ static void register_image_loader(
+ const std::string &device_type,
+ const loader_fcn_t &loader_fcn,
+ const std::string &recovery_instructions
+ );
+
+ //! Load firmware and/or FPGA onto a device
+ /*!
+ * \param image_loader_args arguments to pass into image loading function
+ */
+ static bool load(const image_loader_args_t &image_loader_args);
+
+ //! Get the instructions on how to recovery a particular device
+ /*!
+ * These instructions should be queried if the user interrupts an image loading
+ * session, as this will likely leave the device in an unstable state.
+ * \param device_type the "type=foo" value given in an --args option
+ * \return recoverying instructions
+ */
+ static std::string get_recovery_instructions(const std::string &device_type);
+};
+
+}
+
+#endif /* INCLUDED_UHD_IMAGE_LOADER_HPP */
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 10df8e04e..2668c10b9 100644
--- a/host/include/uhd/transport/nirio/nirio_driver_iface.h
+++ b/host/include/uhd/transport/nirio/nirio_driver_iface.h
@@ -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_MACOS)
#include <IOKit/IOKitLib.h>
#endif
@@ -83,7 +87,7 @@ const uint32_t NIRIO_IOCTL_PRE_CLOSE =
typedef HANDLE rio_dev_handle_t;
#elif defined(UHD_PLATFORM_MACOS)
typedef io_connect_t rio_dev_handle_t;
-#else //Unsupported platforms
+#else
typedef int rio_dev_handle_t;
#endif
static const rio_dev_handle_t INVALID_RIO_HANDLE = ((rio_dev_handle_t)-1);
diff --git a/host/include/uhd/transport/nirio/nirio_fifo.h b/host/include/uhd/transport/nirio/nirio_fifo.h
index cd471474d..a0cd7149f 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/nirio/nirio_quirks.h b/host/include/uhd/transport/nirio/nirio_quirks.h
index 8e58f80f1..45ef40394 100644
--- a/host/include/uhd/transport/nirio/nirio_quirks.h
+++ b/host/include/uhd/transport/nirio/nirio_quirks.h
@@ -35,8 +35,8 @@ public:
nirio_quirks() : _tx_stream_count(0) {
}
- UHD_INLINE void register_tx_streams(const uint32_t tx_stream_indices[]) {
- for (size_t i = 0; i < sizeof(tx_stream_indices)/sizeof(*tx_stream_indices); i++) {
+ UHD_INLINE void register_tx_streams(const uint32_t tx_stream_indices[], size_t size) {
+ for (size_t i = 0; i < size; i++) {
_tx_stream_fifo_indices.insert(tx_stream_indices[i]);
}
}
diff --git a/host/include/uhd/transport/tcp_zero_copy.hpp b/host/include/uhd/transport/tcp_zero_copy.hpp
index 52e94fab9..ac282d8a2 100644
--- a/host/include/uhd/transport/tcp_zero_copy.hpp
+++ b/host/include/uhd/transport/tcp_zero_copy.hpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010-2014 Ettus Research LLC
+// Copyright 2010-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
@@ -32,7 +32,7 @@ namespace uhd{ namespace transport{
*/
struct UHD_API tcp_zero_copy : public virtual zero_copy_if
{
- virtual ~tcp_zero_copy(void) = 0;
+ virtual ~tcp_zero_copy(void);
/*!
* Make a new zero copy TCP transport:
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/transport/zero_copy.hpp b/host/include/uhd/transport/zero_copy.hpp
index 9ff3042aa..de1b17e1a 100644
--- a/host/include/uhd/transport/zero_copy.hpp
+++ b/host/include/uhd/transport/zero_copy.hpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010-2012 Ettus Research LLC
+// Copyright 2010-2012,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/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..90559ff5f 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_dict 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 7ac38f84b..8d5dc2e5f 100644
--- a/host/include/uhd/usrp/multi_usrp.hpp
+++ b/host/include/uhd/usrp/multi_usrp.hpp
@@ -1,5 +1,5 @@
//
-// Copyright 2010-2012,2014 Ettus Research LLC
+// Copyright 2010-2012,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
@@ -22,6 +22,7 @@
#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
@@ -37,6 +38,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>
@@ -157,6 +159,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
*/
@@ -492,6 +499,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 enable 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
@@ -506,6 +541,18 @@ public:
}
/*!
+ * Return the normalized RX gain value.
+ *
+ * See set_normalized_rx_gain() for a discussion of normalized
+ * gains.
+ *
+ * \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
@@ -617,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.
*
@@ -730,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
@@ -744,6 +811,18 @@ public:
}
/*!
+ * Return the normalized TX gain value.
+ *
+ * See set_normalized_rx_gain() for a discussion of normalized
+ * gains.
+ *
+ * \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
@@ -895,6 +974,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/usrp_clock/CMakeLists.txt b/host/include/uhd/usrp_clock/CMakeLists.txt
index 7cd5aa9d3..a116e4982 100644
--- a/host/include/uhd/usrp_clock/CMakeLists.txt
+++ b/host/include/uhd/usrp_clock/CMakeLists.txt
@@ -1,5 +1,5 @@
#
-# Copyright 2014 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
@@ -18,6 +18,6 @@
UHD_INSTALL(FILES
octoclock_eeprom.hpp
multi_usrp_clock.hpp
- DESTINATION ${INCLUDE_DIR}/uhd/octoclock
+ DESTINATION ${INCLUDE_DIR}/uhd/usrp_clock
COMPONENT headers
)
diff --git a/host/include/uhd/utils/math.hpp b/host/include/uhd/utils/math.hpp
index 2937ba802..ef7bfb6b7 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 0dbee3446..cc054b019 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 */
diff --git a/host/include/uhd/utils/soft_register.hpp b/host/include/uhd/utils/soft_register.hpp
new file mode 100644
index 000000000..d3537a618
--- /dev/null
+++ b/host/include/uhd/utils/soft_register.hpp
@@ -0,0 +1,312 @@
+//
+// 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_UTILS_SOFT_REGISTER_HPP
+#define INCLUDED_UHD_UTILS_SOFT_REGISTER_HPP
+
+#include <boost/cstdint.hpp>
+#include <boost/noncopyable.hpp>
+#include <uhd/types/wb_iface.hpp>
+#include <uhd/exception.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/locks.hpp>
+
+#define UHD_DEFINE_SOFT_REG_FIELD(name, width, shift) \
+ static const uhd::soft_reg_field_t name = (((shift & 0xFF) << 8) | (width & 0xFF))
+
+namespace uhd {
+
+/* A register field is defined as a tuple of the mask and the shift.
+ * It can be used to make read-modify-write operations more convenient
+ * For efficiency reasons, it is recommended to always use a constant
+ * of this type because it will get optimized out by the compiler and
+ * will result in zero memory overhead
+ */
+typedef boost::uint32_t soft_reg_field_t;
+
+namespace soft_reg_field {
+ inline size_t width(const soft_reg_field_t field) {
+ return (field & 0xFF);
+ }
+
+ inline size_t shift(const soft_reg_field_t field) {
+ return ((field >> 8) & 0xFF);
+ }
+
+ template<typename data_t>
+ inline size_t mask(const soft_reg_field_t field) {
+ return ((static_cast<data_t>(1)<<width(field))-1)<<shift(field);
+ }
+}
+
+/*!
+ * Soft register object that holds offset, soft-copy and the control iface.
+ * Methods give convenient field-level access to soft-copy and the ability
+ * to do read-modify-write operations.
+ */
+template<typename reg_data_t, bool readable, bool writeable>
+class UHD_API soft_register_t : public boost::noncopyable {
+public:
+ typedef boost::shared_ptr< soft_register_t<reg_data_t, readable, writeable> > sptr;
+
+ /*!
+ * Generic constructor for all soft_register types
+ */
+ soft_register_t(wb_iface::wb_addr_type wr_addr, wb_iface::wb_addr_type rd_addr):
+ _iface(NULL), _wr_addr(wr_addr), _rd_addr(rd_addr), _soft_copy(0)
+ {}
+
+ /*!
+ * Constructor for read-only, write-only registers and read-write registers
+ * with rd_addr == wr_addr
+ */
+ soft_register_t(wb_iface::wb_addr_type addr):
+ _iface(NULL), _wr_addr(addr), _rd_addr(addr), _soft_copy(0)
+ {}
+
+ /*!
+ * Initialize the register when the underlying bus is usable.
+ * Can be optionally synced with hardware.
+ * NOTE: Memory management of the iface is up to the caller
+ */
+ inline void initialize(wb_iface& iface, bool sync = false)
+ {
+ _iface = &iface;
+
+ //Synchronize with hardware. For RW register, flush THEN refresh.
+ if (sync && writeable) flush();
+ if (sync && readable) refresh();
+ }
+
+ /*!
+ * Update specified field in the soft-copy with the arg value.
+ * Performs a read-modify-write operation so all other field are preserved.
+ * NOTE: This does not write the value to hardware.
+ */
+ inline void set(const soft_reg_field_t field, const reg_data_t value)
+ {
+ _soft_copy = (_soft_copy & ~soft_reg_field::mask<reg_data_t>(field)) |
+ ((value << soft_reg_field::shift(field)) & soft_reg_field::mask<reg_data_t>(field));
+ }
+
+ /*!
+ * Get the value of the specified field from the soft-copy.
+ * NOTE: This does not read anything from hardware.
+ */
+ inline reg_data_t get(const soft_reg_field_t field)
+ {
+ return (_soft_copy & soft_reg_field::mask<reg_data_t>(field)) >> soft_reg_field::shift(field);
+ }
+
+ /*!
+ * Write the contents of the soft-copy to hardware.
+ */
+ inline void flush()
+ {
+ if (writeable && _iface) {
+ if (sizeof(reg_data_t) <= 2) {
+ _iface->poke16(_wr_addr, static_cast<boost::uint16_t>(_soft_copy));
+ } else if (sizeof(reg_data_t) <= 4) {
+ _iface->poke32(_wr_addr, static_cast<boost::uint32_t>(_soft_copy));
+ } else if (sizeof(reg_data_t) <= 8) {
+ _iface->poke64(_wr_addr, static_cast<boost::uint64_t>(_soft_copy));
+ } else {
+ throw uhd::not_implemented_error("soft_register only supports up to 64 bits.");
+ }
+ } else {
+ throw uhd::not_implemented_error("soft_register is not writable.");
+ }
+ }
+
+ /*!
+ * Read the contents of the register from hardware and update the soft copy.
+ */
+ inline void refresh()
+ {
+ if (readable && _iface) {
+ if (sizeof(reg_data_t) <= 2) {
+ _soft_copy = static_cast<reg_data_t>(_iface->peek16(_rd_addr));
+ } else if (sizeof(reg_data_t) <= 4) {
+ _soft_copy = static_cast<reg_data_t>(_iface->peek32(_rd_addr));
+ } else if (sizeof(reg_data_t) <= 8) {
+ _soft_copy = static_cast<reg_data_t>(_iface->peek64(_rd_addr));
+ } else {
+ throw uhd::not_implemented_error("soft_register only supports up to 64 bits.");
+ }
+ } else {
+ throw uhd::not_implemented_error("soft_register is not readable.");
+ }
+ }
+
+ /*!
+ * Shortcut for a set and a flush.
+ */
+ inline void write(const soft_reg_field_t field, const reg_data_t value)
+ {
+ set(field, value);
+ flush();
+ }
+
+ /*!
+ * Shortcut for refresh and get
+ */
+ inline reg_data_t read(const soft_reg_field_t field)
+ {
+ refresh();
+ return get(field);
+ }
+
+private:
+ wb_iface* _iface;
+ const wb_iface::wb_addr_type _wr_addr;
+ const wb_iface::wb_addr_type _rd_addr;
+ reg_data_t _soft_copy;
+};
+
+/*!
+ * A synchronized soft register object.
+ * All operations in the synchronized register are serialized.
+ */
+template<typename reg_data_t, bool readable, bool writeable>
+class UHD_API soft_register_sync_t : public soft_register_t<reg_data_t, readable, writeable> {
+public:
+ typedef boost::shared_ptr< soft_register_sync_t<reg_data_t, readable, writeable> > sptr;
+
+ soft_register_sync_t(wb_iface::wb_addr_type wr_addr, wb_iface::wb_addr_type rd_addr):
+ soft_register_t<reg_data_t, readable, writeable>(wr_addr, rd_addr), _mutex()
+ {}
+
+ soft_register_sync_t(wb_iface::wb_addr_type addr):
+ soft_register_t<reg_data_t, readable, writeable>(addr), _mutex()
+ {}
+
+ inline void initialize(wb_iface& iface, bool sync = false)
+ {
+ boost::lock_guard<boost::mutex> lock(_mutex);
+ soft_register_t<reg_data_t, readable, writeable>::initialize(iface, sync);
+ }
+
+ inline void set(const soft_reg_field_t field, const reg_data_t value)
+ {
+ boost::lock_guard<boost::mutex> lock(_mutex);
+ soft_register_t<reg_data_t, readable, writeable>::set(field, value);
+ }
+
+ inline reg_data_t get(const soft_reg_field_t field)
+ {
+ boost::lock_guard<boost::mutex> lock(_mutex);
+ return soft_register_t<reg_data_t, readable, writeable>::get(field);
+ }
+
+ inline void flush()
+ {
+ boost::lock_guard<boost::mutex> lock(_mutex);
+ soft_register_t<reg_data_t, readable, writeable>::flush();
+ }
+
+ inline void refresh()
+ {
+ boost::lock_guard<boost::mutex> lock(_mutex);
+ soft_register_t<reg_data_t, readable, writeable>::refresh();
+ }
+
+ inline void write(const soft_reg_field_t field, const reg_data_t value)
+ {
+ boost::lock_guard<boost::mutex> lock(_mutex);
+ soft_register_t<reg_data_t, readable, writeable>::write(field, value);
+ }
+
+ inline reg_data_t read(const soft_reg_field_t field)
+ {
+ boost::lock_guard<boost::mutex> lock(_mutex);
+ return soft_register_t<reg_data_t, readable, writeable>::read(field);
+ }
+
+private:
+ boost::mutex _mutex;
+};
+
+/*
+ * Register Shortcut Formats:
+ * - soft_reg<bits>_<mode>_t: Soft register object with an unsynchronized soft-copy.
+ * Thread unsafe but lightweight. Mostly const propagated.
+ * - soft_reg<bits>_<mode>_sync_t: Soft register object with a synchronized soft-copy.
+ * Thread safe but with memory/speed overhead.
+ * where:
+ * - <bits> = {16, 32 or 64}
+ * - <mode> = {wo(write-only), rw(read-write) or ro(read-only)}
+ *
+ */
+
+//16-bit shortcuts
+typedef soft_register_t<boost::uint16_t, false, true> soft_reg16_wo_t;
+typedef soft_register_t<boost::uint16_t, true, false> soft_reg16_ro_t;
+typedef soft_register_t<boost::uint16_t, true, true> soft_reg16_rw_t;
+typedef soft_register_sync_t<boost::uint16_t, false, true> soft_reg16_wo_sync_t;
+typedef soft_register_sync_t<boost::uint16_t, true, false> soft_reg16_ro_sync_t;
+typedef soft_register_sync_t<boost::uint16_t, true, true> soft_reg16_rw_sync_t;
+//32-bit shortcuts
+typedef soft_register_t<boost::uint32_t, false, true> soft_reg32_wo_t;
+typedef soft_register_t<boost::uint32_t, true, false> soft_reg32_ro_t;
+typedef soft_register_t<boost::uint32_t, true, true> soft_reg32_rw_t;
+typedef soft_register_sync_t<boost::uint32_t, false, true> soft_reg32_wo_sync_t;
+typedef soft_register_sync_t<boost::uint32_t, true, false> soft_reg32_ro_sync_t;
+typedef soft_register_sync_t<boost::uint32_t, true, true> soft_reg32_rw_sync_t;
+//64-bit shortcuts
+typedef soft_register_t<boost::uint64_t, false, true> soft_reg64_wo_t;
+typedef soft_register_t<boost::uint64_t, true, false> soft_reg64_ro_t;
+typedef soft_register_t<boost::uint64_t, true, true> soft_reg64_rw_t;
+typedef soft_register_sync_t<boost::uint64_t, false, true> soft_reg64_wo_sync_t;
+typedef soft_register_sync_t<boost::uint64_t, true, false> soft_reg64_ro_sync_t;
+typedef soft_register_sync_t<boost::uint64_t, true, true> soft_reg64_rw_sync_t;
+
+
+/*
+ * Usage example
+ *
+ //===Define bit width, RW mode, and synchronization using base class===
+ class example_reg_t : public soft_reg32_wo_sync_t (or soft_reg32_wo_t) {
+ public:
+ //===Define all the fields===
+ UHD_DEFINE_SOFT_REG_FIELD(FIELD0, 1, 0); //[0]
+ UHD_DEFINE_SOFT_REG_FIELD(FIELD1, 15, 1); //[15:1]
+ UHD_DEFINE_SOFT_REG_FIELD(FIELD2, 16, 16); //[31:16]
+
+ example_reg_t(): //ctor with no args
+ soft_reg32_wo_t(SR_CORE_EXAMPLE_REG_OFFSET)) //===Bind to offset===
+ {
+ //===Set Initial values===
+ set(FIELD0, 0);
+ set(FIELD1, 1);
+ set(FIELD2, 0xFFFF);
+ }
+ }; //===Full register definition encapsulated in one class===
+
+ void main() {
+ example_reg_t reg_obj;
+ reg_obj.initialize(iface);
+ reg_obj.write(example_reg_t::FIELD2, 0x1234);
+
+ example_reg_t::sptr reg_sptr = boost::make_shared<example_reg_t>();
+ reg_obj->initialize(iface);
+ reg_obj->write(example_reg_t::FIELD2, 0x1234);
+ }
+*/
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_UTILS_SOFT_REGISTER_HPP */