diff options
Diffstat (limited to 'host/include')
61 files changed, 5137 insertions, 0 deletions
diff --git a/host/include/CMakeLists.txt b/host/include/CMakeLists.txt new file mode 100644 index 000000000..3f7ca2cb7 --- /dev/null +++ b/host/include/CMakeLists.txt @@ -0,0 +1,19 @@ +# +# Copyright 2010 Ettus Research LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + + +ADD_SUBDIRECTORY(uhd) diff --git a/host/include/uhd/CMakeLists.txt b/host/include/uhd/CMakeLists.txt new file mode 100644 index 000000000..ad528c9fb --- /dev/null +++ b/host/include/uhd/CMakeLists.txt @@ -0,0 +1,31 @@ +# +# Copyright 2010 Ettus Research LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + + +ADD_SUBDIRECTORY(transport) +ADD_SUBDIRECTORY(types) +ADD_SUBDIRECTORY(usrp) +ADD_SUBDIRECTORY(utils) + +INSTALL(FILES + config.hpp + device.hpp + device.ipp + version.hpp + wax.hpp + DESTINATION ${INCLUDE_DIR}/uhd +) diff --git a/host/include/uhd/config.hpp b/host/include/uhd/config.hpp new file mode 100644 index 000000000..dacd3a96b --- /dev/null +++ b/host/include/uhd/config.hpp @@ -0,0 +1,115 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_CONFIG_HPP +#define INCLUDED_UHD_CONFIG_HPP + +// suppress warnings +#include <boost/config.hpp> +#ifdef BOOST_MSVC +//# pragma warning(push) +//# pragma warning(disable: 4511) // copy constructor can't not be generated +//# pragma warning(disable: 4512) // assignment operator can't not be generated +//# pragma warning(disable: 4100) // unreferenced formal parameter +//# pragma warning(disable: 4996) // <symbol> was declared deprecated +//# pragma warning(disable: 4355) // 'this' : used in base member initializer list +//# pragma warning(disable: 4706) // assignment within conditional expression +# pragma warning(disable: 4251) // class 'A<T>' needs to have dll-interface to be used by clients of class 'B' +//# pragma warning(disable: 4127) // conditional expression is constant +//# pragma warning(disable: 4290) // C++ exception specification ignored except to ... +# pragma warning(disable: 4180) // qualifier applied to function type has no meaning; ignored +# pragma warning(disable: 4275) // non dll-interface class ... used as base for dll-interface class ... +//# pragma warning(disable: 4267) // 'var' : conversion from 'size_t' to 'type', possible loss of data +//# pragma warning(disable: 4511) // 'class' : copy constructor could not be generated +# pragma warning(disable: 4250) // 'class' : inherits 'method' via dominance +#endif + +// define logical operators +#ifdef BOOST_MSVC + #include <ciso646> +#endif + +// define ssize_t +#ifdef BOOST_MSVC + #include <cstddef> + typedef ptrdiff_t ssize_t; +#endif + +// http://gcc.gnu.org/wiki/Visibility +// Generic helper definitions for shared library support +#if defined(BOOST_HAS_DECLSPEC) + #define UHD_HELPER_DLL_IMPORT __declspec(dllimport) + #define UHD_HELPER_DLL_EXPORT __declspec(dllexport) + #define UHD_HELPER_DLL_LOCAL +#elif defined(__GNUG__) && __GNUG__ >= 4 + #define UHD_HELPER_DLL_IMPORT __attribute__ ((visibility("default"))) + #define UHD_HELPER_DLL_EXPORT __attribute__ ((visibility("default"))) + #define UHD_HELPER_DLL_LOCAL __attribute__ ((visibility("hidden"))) +#else + #define UHD_HELPER_DLL_IMPORT + #define UHD_HELPER_DLL_EXPORT + #define UHD_HELPER_DLL_LOCAL +#endif + +// Now we use the generic helper definitions above to define UHD_API and UHD_LOCAL. +// UHD_API is used for the public API symbols. It either DLL imports or DLL exports (or does nothing for static build) +// UHD_LOCAL is used for non-api symbols. + +#define UHD_DLL // defined here, put into configuration if we need to make static libs + +#ifdef UHD_DLL // defined if UHD is compiled as a DLL + #ifdef UHD_DLL_EXPORTS // defined if we are building the UHD DLL (instead of using it) + #define UHD_API UHD_HELPER_DLL_EXPORT + #else + #define UHD_API UHD_HELPER_DLL_IMPORT + #endif // UHD_DLL_EXPORTS + #define UHD_LOCAL UHD_HELPER_DLL_LOCAL +#else // UHD_DLL is not defined: this means UHD is a static lib. + #define UHD_API + #define UHD_LOCAL +#endif // UHD_DLL + +// Define force inline macro +#if defined(BOOST_MSVC) + #define UHD_INLINE __forceinline +#elif defined(__GNUG__) && __GNUG__ >= 4 + #define UHD_INLINE inline __attribute__((always_inline)) +#else + #define UHD_INLINE inline +#endif + +// Define deprecated attribute macro +#if defined(BOOST_MSVC) + #define UHD_DEPRECATED __declspec(deprecated) +#elif defined(__GNUG__) && __GNUG__ >= 4 + #define UHD_DEPRECATED __attribute__ ((deprecated)) +#else + #define UHD_DEPRECATED +#endif + +// Platform defines for conditional parts of headers: +// Taken from boost/config/select_platform_config.hpp, +// however, we define macros, not strings for platforms. +#if defined(linux) || defined(__linux) || defined(__linux__) + #define UHD_PLATFORM_LINUX +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) + #define UHD_PLATFORM_WIN32 +#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) + #define UHD_PLATFORM_MACOS +#endif + +#endif /* INCLUDED_UHD_CONFIG_HPP */ diff --git a/host/include/uhd/device.hpp b/host/include/uhd/device.hpp new file mode 100644 index 000000000..c48b3dfff --- /dev/null +++ b/host/include/uhd/device.hpp @@ -0,0 +1,234 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_DEVICE_HPP +#define INCLUDED_UHD_DEVICE_HPP + +#include <uhd/config.hpp> +#include <uhd/types/device_addr.hpp> +#include <uhd/types/metadata.hpp> +#include <uhd/types/io_type.hpp> +#include <uhd/wax.hpp> +#include <boost/utility.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/function.hpp> +#include <boost/asio/buffer.hpp> +#include <vector> + +namespace uhd{ + +/*! + * The usrp device interface represents the usrp hardware. + * The api allows for discovery, configuration, and streaming. + */ +class UHD_API device : boost::noncopyable, public wax::obj{ + +public: + typedef boost::shared_ptr<device> sptr; + typedef boost::function<device_addrs_t(const device_addr_t &)> find_t; + typedef boost::function<sptr(const device_addr_t &)> make_t; + + //! A reasonable default timeout for receive + static const size_t default_recv_timeout_ms = 100; + + /*! + * Register a device into the discovery and factory system. + * + * \param find a function that discovers devices + * \param make a factory function that makes a device + */ + static void register_device( + const find_t &find, + const make_t &make + ); + + /*! + * \brief Find usrp devices attached to the host. + * + * The hint device address should be used to narrow down the search + * to particular transport types and/or transport arguments. + * + * \param hint a partially (or fully) filled in device address + * \return a vector of device addresses for all usrps on the system + */ + static device_addrs_t find(const device_addr_t &hint); + + /*! + * \brief Create a new usrp device from the device address hint. + * + * The make routine will call find and pick one of the results. + * By default, the first result will be used to create a new device. + * Use the which parameter as an index into the list of results. + * + * \param hint a partially (or fully) filled in device address + * \param which which address to use when multiple are found + * \return a shared pointer to a new device instance + */ + static sptr make(const device_addr_t &hint, size_t which = 0); + + /*! + * Send modes for the device send routine. + */ + enum send_mode_t{ + //! Tells the send routine to send the entire buffer + SEND_MODE_FULL_BUFF = 0, + //! Tells the send routine to return after one packet + SEND_MODE_ONE_PACKET = 1 + }; + + /*! + * Recv modes for the device recv routine. + */ + enum recv_mode_t{ + //! Tells the recv routine to recv the entire buffer + RECV_MODE_FULL_BUFF = 0, + //! Tells the recv routine to return after one packet + RECV_MODE_ONE_PACKET = 1 + }; + + /*! + * Send buffers containing IF data described by the metadata. + * + * Send handles fragmentation as follows: + * If the buffer has more samples than the maximum per packet, + * the send method will fragment the samples across several packets. + * Send will respect the burst flags when fragmenting to ensure + * that start of burst can only be set on the first fragment and + * that end of burst can only be set on the final fragment. + * Fragmentation only applies in the full buffer send mode. + * + * This is a blocking call and will not return until the number + * of samples returned have been read out of each buffer. + * + * \param buffs a vector of read-only memory containing IF data + * \param nsamps_per_buff the number of samples to send, per buffer + * \param metadata data describing the buffer's contents + * \param io_type the type of data loaded in the buffer + * \param send_mode tells send how to unload the buffer + * \return the number of samples sent + */ + virtual size_t send( + const std::vector<const void *> &buffs, + size_t nsamps_per_buff, + const tx_metadata_t &metadata, + const io_type_t &io_type, + send_mode_t send_mode + ) = 0; + + /*! + * Convenience wrapper for send that takes a single buffer. + */ + size_t send( + const void *buff, + size_t nsamps_per_buff, + const tx_metadata_t &metadata, + const io_type_t &io_type, + send_mode_t send_mode + ); + + //! Deprecated + size_t send( + const boost::asio::const_buffer &, const tx_metadata_t &, + const io_type_t &, send_mode_t send_mode + ); + + /*! + * Receive buffers containing IF data described by the metadata. + * + * Receive handles fragmentation as follows: + * If the buffer has insufficient space to hold all samples + * that were received in a single packet over-the-wire, + * then the buffer will be completely filled and the implementation + * will hold a pointer into the remaining portion of the packet. + * Subsequent calls will load from the remainder of the packet, + * and will flag the metadata to show that this is a fragment. + * The next call to receive, after the remainder becomes exahausted, + * will perform an over-the-wire receive as usual. + * See the rx metadata fragment flags and offset fields for details. + * + * This is a blocking call and will not return until the number + * of samples returned have been written into each buffer or timeout. + * + * When using the full buffer recv mode, the metadata only applies + * to the first packet received and written into the recv buffers. + * Use the one packet recv mode to get per packet metadata. + * + * \param buffs a vector of writable memory to fill with IF data + * \param nsamps_per_buff the size of each buffer in number of samples + * \param metadata data to fill describing the buffer + * \param io_type the type of data to fill into the buffer + * \param recv_mode tells recv how to load the buffer + * \param timeout_ms the timeout in milliseconds to wait for a packet + * \return the number of samples received or 0 on error + */ + virtual size_t recv( + const std::vector<void *> &buffs, + size_t nsamps_per_buff, + rx_metadata_t &metadata, + const io_type_t &io_type, + recv_mode_t recv_mode, + size_t timeout_ms = default_recv_timeout_ms + ) = 0; + + /*! + * Convenience wrapper for recv that takes a single buffer. + */ + size_t recv( + void *buff, + size_t nsamps_per_buff, + rx_metadata_t &metadata, + const io_type_t &io_type, + recv_mode_t recv_mode, + size_t timeout_ms = default_recv_timeout_ms + ); + + //! Deprecated + size_t recv( + const boost::asio::mutable_buffer &, rx_metadata_t &, + const io_type_t &, recv_mode_t + ); + + /*! + * Get the maximum number of samples per packet on send. + * \return the number of samples + */ + virtual size_t get_max_send_samps_per_packet(void) const = 0; + + /*! + * Get the maximum number of samples per packet on recv. + * \return the number of samples + */ + virtual size_t get_max_recv_samps_per_packet(void) const = 0; + + /*! + * Receive and asynchronous message from the device. + * \param async_metadata the metadata to be filled in + * \param timeout_ms the timeout in milliseconds to wait for a message + * \return true when the async_metadata is valid, false for timeout + */ + virtual bool recv_async_msg( + async_metadata_t &async_metadata, + size_t timeout_ms = default_recv_timeout_ms + ) = 0; + +}; + +} //namespace uhd + +#include <uhd/device.ipp> + +#endif /* INCLUDED_UHD_DEVICE_HPP */ diff --git a/host/include/uhd/device.ipp b/host/include/uhd/device.ipp new file mode 100644 index 000000000..603c52859 --- /dev/null +++ b/host/include/uhd/device.ipp @@ -0,0 +1,80 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_DEVICE_IPP +#define INCLUDED_UHD_DEVICE_IPP + +namespace uhd{ + + UHD_INLINE size_t device::send( + const void *buff, + size_t nsamps_per_buff, + const tx_metadata_t &metadata, + const io_type_t &io_type, + send_mode_t send_mode + ){ + return this->send( + std::vector<const void *>(1, buff), + nsamps_per_buff, metadata, + io_type, send_mode + ); + } + + UHD_DEPRECATED UHD_INLINE size_t device::send( + const boost::asio::const_buffer &buff, + const tx_metadata_t &metadata, + const io_type_t &io_type, + send_mode_t send_mode + ){ + return this->send( + boost::asio::buffer_cast<const void *>(buff), + boost::asio::buffer_size(buff)/io_type.size, + metadata, io_type, send_mode + ); + } + + UHD_INLINE size_t device::recv( + void *buff, + size_t nsamps_per_buff, + rx_metadata_t &metadata, + const io_type_t &io_type, + recv_mode_t recv_mode, + size_t timeout_ms + ){ + return this->recv( + std::vector<void *>(1, buff), + nsamps_per_buff, metadata, + io_type, recv_mode, timeout_ms + ); + } + + UHD_DEPRECATED UHD_INLINE size_t device::recv( + const boost::asio::mutable_buffer &buff, + rx_metadata_t &metadata, + const io_type_t &io_type, + recv_mode_t recv_mode + ){ + return this->recv( + boost::asio::buffer_cast<void *>(buff), + boost::asio::buffer_size(buff)/io_type.size, + metadata, io_type, recv_mode + ); + } + +} //namespace uhd + +#endif /* INCLUDED_UHD_DEVICE_IPP */ diff --git a/host/include/uhd/transport/CMakeLists.txt b/host/include/uhd/transport/CMakeLists.txt new file mode 100644 index 000000000..93e9a6485 --- /dev/null +++ b/host/include/uhd/transport/CMakeLists.txt @@ -0,0 +1,31 @@ +# +# Copyright 2010 Ettus Research LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + + +INSTALL(FILES + alignment_buffer.hpp + alignment_buffer.ipp + bounded_buffer.hpp + bounded_buffer.ipp + convert_types.hpp + if_addrs.hpp + udp_simple.hpp + udp_zero_copy.hpp + vrt_if_packet.hpp + zero_copy.hpp + DESTINATION ${INCLUDE_DIR}/uhd/transport +) diff --git a/host/include/uhd/transport/alignment_buffer.hpp b/host/include/uhd/transport/alignment_buffer.hpp new file mode 100644 index 000000000..29ba74efc --- /dev/null +++ b/host/include/uhd/transport/alignment_buffer.hpp @@ -0,0 +1,72 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TRANSPORT_ALIGNMENT_BUFFER_HPP +#define INCLUDED_UHD_TRANSPORT_ALIGNMENT_BUFFER_HPP + +#include <uhd/config.hpp> +#include <uhd/transport/bounded_buffer.hpp> //time_duration_t +#include <boost/shared_ptr.hpp> +#include <vector> + +namespace uhd{ namespace transport{ + + /*! + * Implement a templated alignment buffer: + * Used for aligning asynchronously pushed elements with matching ids. + */ + template <typename elem_type, typename seq_type> class alignment_buffer{ + public: + typedef boost::shared_ptr<alignment_buffer<elem_type, seq_type> > sptr; + + /*! + * Make a new alignment buffer object. + * \param capacity the maximum elements per index + * \param width the number of elements to align + */ + static sptr make(size_t capacity, size_t width); + + /*! + * Push an element with sequence id into the buffer at index. + * \param elem the element to push + * \param seq the sequence identifier + * \param index the buffer index + * \return true if the element fit without popping for space + */ + virtual bool push_with_pop_on_full( + const elem_type &elem, + const seq_type &seq, + size_t index + ) = 0; + + /*! + * Pop an aligned set of elements from this alignment buffer. + * \param elems a collection to store the aligned elements + * \param time the timeout time + * \return false when the operation times out + */ + virtual bool pop_elems_with_timed_wait( + std::vector<elem_type> &elems, + const time_duration_t &time + ) = 0; + }; + +}} //namespace + +#include <uhd/transport/alignment_buffer.ipp> + +#endif /* INCLUDED_UHD_TRANSPORT_ALIGNMENT_BUFFER_HPP */ diff --git a/host/include/uhd/transport/alignment_buffer.ipp b/host/include/uhd/transport/alignment_buffer.ipp new file mode 100644 index 000000000..61b3b60f5 --- /dev/null +++ b/host/include/uhd/transport/alignment_buffer.ipp @@ -0,0 +1,147 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TRANSPORT_ALIGNMENT_BUFFER_IPP +#define INCLUDED_UHD_TRANSPORT_ALIGNMENT_BUFFER_IPP + +#include <uhd/transport/bounded_buffer.hpp> +#include <boost/thread/condition_variable.hpp> +#include <utility> + +namespace uhd{ namespace transport{ namespace{ /*anon*/ + + /*! + * Imlement a templated alignment buffer: + * Used for aligning asynchronously pushed elements with matching ids. + */ + template <typename elem_type, typename seq_type> + class alignment_buffer_impl : public alignment_buffer<elem_type, seq_type>{ + public: + + alignment_buffer_impl(size_t capacity, size_t width) : _last_seqs(width){ + for (size_t i = 0; i < width; i++){ + _buffs.push_back(bounded_buffer<buff_contents_type>::make(capacity)); + _all_indexes.push_back(i); + } + _there_was_a_clear = false; + } + + UHD_INLINE bool push_with_pop_on_full( + const elem_type &elem, + const seq_type &seq, + size_t index + ){ + //clear the buffer for this index if the seqs are mis-ordered + if (seq < _last_seqs[index]){ + _buffs[index]->clear(); + _there_was_a_clear = true; + } _last_seqs[index] = seq; + return _buffs[index]->push_with_pop_on_full(buff_contents_type(elem, seq)); + } + + UHD_INLINE bool pop_elems_with_timed_wait( + std::vector<elem_type> &elems, + const time_duration_t &time + ){ + boost::system_time exit_time = boost::get_system_time() + time; + buff_contents_type buff_contents_tmp; + std::list<size_t> indexes_to_do(_all_indexes); + + //do an initial pop to load an initial sequence id + size_t index = indexes_to_do.front(); + if (not _buffs[index]->pop_with_timed_wait( + buff_contents_tmp, exit_time - boost::get_system_time() + )) return false; + elems[index] = buff_contents_tmp.first; + seq_type expected_seq_id = buff_contents_tmp.second; + indexes_to_do.pop_front(); + + //get an aligned set of elements from the buffers: + while(indexes_to_do.size() != 0){ + + //respond to a clear by starting from scratch + if(_there_was_a_clear){ + _there_was_a_clear = false; + indexes_to_do = _all_indexes; + index = indexes_to_do.front(); + if (not _buffs[index]->pop_with_timed_wait( + buff_contents_tmp, exit_time - boost::get_system_time() + )) return false; + elems[index] = buff_contents_tmp.first; + expected_seq_id = buff_contents_tmp.second; + indexes_to_do.pop_front(); + } + + //pop an element off for this index + index = indexes_to_do.front(); + if (not _buffs[index]->pop_with_timed_wait( + buff_contents_tmp, exit_time - boost::get_system_time() + )) return false; + + //if the sequence id matches: + // store the popped element into the output, + // remove this index from the list and continue + if (buff_contents_tmp.second == expected_seq_id){ + elems[index] = buff_contents_tmp.first; + indexes_to_do.pop_front(); + continue; + } + + //if the sequence id is older: + // continue with the same index to try again + if (buff_contents_tmp.second < expected_seq_id){ + continue; + } + + //if the sequence id is newer: + // store the popped element into the output, + // add all other indexes back into the list + if (buff_contents_tmp.second > expected_seq_id){ + elems[index] = buff_contents_tmp.first; + expected_seq_id = buff_contents_tmp.second; + indexes_to_do = _all_indexes; + indexes_to_do.remove(index); + continue; + } + } + return true; + } + + private: + //a vector of bounded buffers for each index + typedef std::pair<elem_type, seq_type> buff_contents_type; + std::vector<typename bounded_buffer<buff_contents_type>::sptr> _buffs; + std::vector<seq_type> _last_seqs; + std::list<size_t> _all_indexes; + bool _there_was_a_clear; + }; + +}}} //namespace + +namespace uhd{ namespace transport{ + + template <typename elem_type, typename seq_type> + typename alignment_buffer<elem_type, seq_type>::sptr + alignment_buffer<elem_type, seq_type>::make(size_t capacity, size_t width){ + return typename alignment_buffer<elem_type, seq_type>::sptr( + new alignment_buffer_impl<elem_type, seq_type>(capacity, width) + ); + } + +}} //namespace + +#endif /* INCLUDED_UHD_TRANSPORT_ALIGNMENT_BUFFER_IPP */ diff --git a/host/include/uhd/transport/bounded_buffer.hpp b/host/include/uhd/transport/bounded_buffer.hpp new file mode 100644 index 000000000..d1deece96 --- /dev/null +++ b/host/include/uhd/transport/bounded_buffer.hpp @@ -0,0 +1,98 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TRANSPORT_BOUNDED_BUFFER_HPP +#define INCLUDED_UHD_TRANSPORT_BOUNDED_BUFFER_HPP + +#include <uhd/config.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/date_time/posix_time/posix_time_types.hpp> + +namespace uhd{ namespace transport{ + + //! typedef for the time duration type for wait operations + typedef boost::posix_time::time_duration time_duration_t; + + /*! + * Implement a templated bounded buffer: + * Used for passing elements between threads in a producer-consumer model. + * The bounded buffer implemented waits and timed waits with condition variables. + * The pop operation blocks on the bounded_buffer to become non empty. + * The push operation blocks on the bounded_buffer to become non full. + */ + template <typename elem_type> class bounded_buffer{ + public: + typedef boost::shared_ptr<bounded_buffer<elem_type> > sptr; + + /*! + * Make a new bounded buffer object. + * \param capacity the bounded_buffer capacity + */ + static sptr make(size_t capacity); + + /*! + * Push a new element into the bounded buffer. + * If the buffer is full prior to the push, + * make room by poping the oldest element. + * \param elem the new element to push + * \return true if the element fit without popping for space + */ + virtual bool push_with_pop_on_full(const elem_type &elem) = 0; + + /*! + * Push a new element into the bounded_buffer. + * Wait until the bounded_buffer becomes non-full. + * \param elem the new element to push + */ + virtual void push_with_wait(const elem_type &elem) = 0; + + /*! + * Push a new element into the bounded_buffer. + * Wait until the bounded_buffer becomes non-full or timeout. + * \param elem the new element to push + * \param time the timeout time + * \return false when the operation times out + */ + virtual bool push_with_timed_wait(const elem_type &elem, const time_duration_t &time) = 0; + + /*! + * Pop an element from the bounded_buffer. + * Wait until the bounded_buffer becomes non-empty. + * \param elem the element reference pop to + */ + virtual void pop_with_wait(elem_type &elem) = 0; + + /*! + * Pop an element from the bounded_buffer. + * Wait until the bounded_buffer becomes non-empty or timeout. + * \param elem the element reference pop to + * \param time the timeout time + * \return false when the operation times out + */ + virtual bool pop_with_timed_wait(elem_type &elem, const time_duration_t &time) = 0; + + /*! + * Clear all elements from the bounded_buffer. + */ + virtual void clear(void) = 0; + }; + +}} //namespace + +#include <uhd/transport/bounded_buffer.ipp> + +#endif /* INCLUDED_UHD_TRANSPORT_BOUNDED_BUFFER_HPP */ diff --git a/host/include/uhd/transport/bounded_buffer.ipp b/host/include/uhd/transport/bounded_buffer.ipp new file mode 100644 index 000000000..e106e229e --- /dev/null +++ b/host/include/uhd/transport/bounded_buffer.ipp @@ -0,0 +1,112 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TRANSPORT_BOUNDED_BUFFER_IPP +#define INCLUDED_UHD_TRANSPORT_BOUNDED_BUFFER_IPP + +#include <boost/bind.hpp> +#include <boost/circular_buffer.hpp> +#include <boost/thread/condition.hpp> + +namespace uhd{ namespace transport{ namespace{ /*anon*/ + + template <typename elem_type> + class bounded_buffer_impl : public bounded_buffer<elem_type>{ + public: + + bounded_buffer_impl(size_t capacity) : _buffer(capacity){ + /* NOP */ + } + + UHD_INLINE bool push_with_pop_on_full(const elem_type &elem){ + boost::unique_lock<boost::mutex> lock(_mutex); + if(_buffer.full()){ + _buffer.pop_back(); + _buffer.push_front(elem); + lock.unlock(); + _empty_cond.notify_one(); + return false; + } + else{ + _buffer.push_front(elem); + lock.unlock(); + _empty_cond.notify_one(); + return true; + } + } + + UHD_INLINE void push_with_wait(const elem_type &elem){ + boost::unique_lock<boost::mutex> lock(_mutex); + _full_cond.wait(lock, boost::bind(&bounded_buffer_impl<elem_type>::not_full, this)); + _buffer.push_front(elem); + lock.unlock(); + _empty_cond.notify_one(); + } + + bool push_with_timed_wait(const elem_type &elem, const time_duration_t &time){ + boost::unique_lock<boost::mutex> lock(_mutex); + if (not _full_cond.timed_wait(lock, time, boost::bind(&bounded_buffer_impl<elem_type>::not_full, this))) return false; + _buffer.push_front(elem); + lock.unlock(); + _empty_cond.notify_one(); + return true; + } + + UHD_INLINE void pop_with_wait(elem_type &elem){ + boost::unique_lock<boost::mutex> lock(_mutex); + _empty_cond.wait(lock, boost::bind(&bounded_buffer_impl<elem_type>::not_empty, this)); + elem = _buffer.back(); _buffer.pop_back(); + lock.unlock(); + _full_cond.notify_one(); + } + + bool pop_with_timed_wait(elem_type &elem, const time_duration_t &time){ + boost::unique_lock<boost::mutex> lock(_mutex); + if (not _empty_cond.timed_wait(lock, time, boost::bind(&bounded_buffer_impl<elem_type>::not_empty, this))) return false; + elem = _buffer.back(); _buffer.pop_back(); + lock.unlock(); + _full_cond.notify_one(); + return true; + } + + UHD_INLINE void clear(void){ + boost::unique_lock<boost::mutex> lock(_mutex); + while (not_empty()) _buffer.pop_back(); + lock.unlock(); + _full_cond.notify_one(); + } + + private: + boost::mutex _mutex; + boost::condition _empty_cond, _full_cond; + boost::circular_buffer<elem_type> _buffer; + + bool not_full(void) const{return not _buffer.full();} + bool not_empty(void) const{return not _buffer.empty();} + }; +}}} //namespace + +namespace uhd{ namespace transport{ + + template <typename elem_type> typename bounded_buffer<elem_type>::sptr + bounded_buffer<elem_type>::make(size_t capacity){ + return typename bounded_buffer<elem_type>::sptr(new bounded_buffer_impl<elem_type>(capacity)); + } + +}} //namespace + +#endif /* INCLUDED_UHD_TRANSPORT_BOUNDED_BUFFER_IPP */ diff --git a/host/include/uhd/transport/convert_types.hpp b/host/include/uhd/transport/convert_types.hpp new file mode 100644 index 000000000..a4d999240 --- /dev/null +++ b/host/include/uhd/transport/convert_types.hpp @@ -0,0 +1,59 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TRANSPORT_CONVERT_TYPES_HPP +#define INCLUDED_UHD_TRANSPORT_CONVERT_TYPES_HPP + +#include <uhd/config.hpp> +#include <uhd/types/io_type.hpp> +#include <uhd/types/otw_type.hpp> + +namespace uhd{ namespace transport{ + +/*! + * Convert IO samples to OWT samples. + * + * \param io_buff memory containing samples + * \param io_type the type of these samples + * \param otw_buff memory to write converted samples + * \param otw_type the type of these samples + * \param num_samps the number of samples in io_buff + */ +UHD_API void convert_io_type_to_otw_type( + const void *io_buff, const io_type_t &io_type, + void *otw_buff, const otw_type_t &otw_type, + size_t num_samps +); + +/*! + * Convert OTW samples to IO samples. + * + * \param otw_buff memory containing samples + * \param otw_type the type of these samples + * \param io_buff memory to write converted samples + * \param io_type the type of these samples + * \param num_samps the number of samples in io_buff + */ +UHD_API void convert_otw_type_to_io_type( + const void *otw_buff, const otw_type_t &otw_type, + void *io_buff, const io_type_t &io_type, + size_t num_samps +); + +}} //namespace + +#endif /* INCLUDED_UHD_TRANSPORT_CONVERT_TYPES_HPP */ diff --git a/host/include/uhd/transport/if_addrs.hpp b/host/include/uhd/transport/if_addrs.hpp new file mode 100644 index 000000000..fbbb35e1d --- /dev/null +++ b/host/include/uhd/transport/if_addrs.hpp @@ -0,0 +1,47 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_IFADDRS_HPP +#define INCLUDED_UHD_IFADDRS_HPP + +#include <uhd/config.hpp> +#include <string> +#include <vector> + +namespace uhd{ namespace transport{ + + /*! + * The address for a network interface. + */ + struct UHD_API if_addrs_t{ + std::string inet; + std::string mask; + std::string bcast; + if_addrs_t(void); + }; + + /*! + * Get a list of network interface addresses. + * The internal implementation is system-dependent. + * \return a vector of if addrs + */ + UHD_API std::vector<if_addrs_t> get_if_addrs(void); + +}} //namespace + + +#endif /* INCLUDED_UHD_IFADDRS_HPP */ diff --git a/host/include/uhd/transport/udp_simple.hpp b/host/include/uhd/transport/udp_simple.hpp new file mode 100644 index 000000000..c84393ecf --- /dev/null +++ b/host/include/uhd/transport/udp_simple.hpp @@ -0,0 +1,84 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TRANSPORT_UDP_SIMPLE_HPP +#define INCLUDED_UHD_TRANSPORT_UDP_SIMPLE_HPP + +#include <uhd/config.hpp> +#include <boost/asio/buffer.hpp> +#include <boost/utility.hpp> +#include <boost/shared_ptr.hpp> + +namespace uhd{ namespace transport{ + +class UHD_API udp_simple : boost::noncopyable{ +public: + typedef boost::shared_ptr<udp_simple> sptr; + + //! The maximum number of bytes per udp packet. + static const size_t mtu = 1500 - 20 - 8; //default ipv4 mtu - ipv4 header - udp header + + /*! + * Make a new connected udp transport: + * This transport is for sending and receiving + * between this host and a single endpoint. + * The primary usage for this transport will be control transactions. + * The underlying implementation is simple and portable (not fast). + * + * The address will be resolved, it can be a host name or ipv4. + * The port will be resolved, it can be a port type or number. + * + * \param addr a string representing the destination address + * \param port a string representing the destination port + */ + static sptr make_connected(const std::string &addr, const std::string &port); + + /*! + * Make a new broadcasting udp transport: + * This transport can send udp broadcast datagrams + * and receive datagrams from multiple sources. + * The primary usage for this transport will be to discover devices. + * + * The address will be resolved, it can be a host name or ipv4. + * The port will be resolved, it can be a port type or number. + * + * \param addr a string representing the destination address + * \param port a string representing the destination port + */ + static sptr make_broadcast(const std::string &addr, const std::string &port); + + /*! + * Send a single buffer. + * Blocks until the data is sent. + * \param buff single asio buffer + * \return the number of bytes sent + */ + virtual size_t send(const boost::asio::const_buffer &buff) = 0; + + /*! + * Receive into the provided buffer. + * Blocks until data is received or a timeout occurs. + * \param buff a mutable buffer to receive into + * \param timeout_ms the timeout in milliseconds + * \return the number of bytes received or zero on timeout + */ + virtual size_t recv(const boost::asio::mutable_buffer &buff, size_t timeout_ms) = 0; +}; + +}} //namespace + +#endif /* INCLUDED_UHD_TRANSPORT_UDP_SIMPLE_HPP */ diff --git a/host/include/uhd/transport/udp_zero_copy.hpp b/host/include/uhd/transport/udp_zero_copy.hpp new file mode 100644 index 000000000..818709973 --- /dev/null +++ b/host/include/uhd/transport/udp_zero_copy.hpp @@ -0,0 +1,66 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TRANSPORT_UDP_ZERO_COPY_HPP +#define INCLUDED_UHD_TRANSPORT_UDP_ZERO_COPY_HPP + +#include <uhd/config.hpp> +#include <uhd/transport/zero_copy.hpp> +#include <boost/shared_ptr.hpp> + +namespace uhd{ namespace transport{ + +/*! + * A zero copy udp transport provides an efficient way to handle data. + * by avoiding the extra copy when recv() or send() is called on the socket. + * Rather, the zero copy transport gives the caller memory references. + * The caller informs the transport when it is finished with the reference. + * + * On linux systems, the zero copy transport can use a kernel packet ring. + * If no platform specific solution is available, make returns a boost asio + * implementation that wraps the functionality around a standard send/recv calls. + */ +class UHD_API udp_zero_copy : public virtual zero_copy_if{ +public: + typedef boost::shared_ptr<udp_zero_copy> sptr; + + /*! + * Make a new zero copy udp transport: + * This transport is for sending and receiving + * between this host and a single endpoint. + * The primary usage for this transport will be data transactions. + * The underlying implementation is fast and platform specific. + * + * The address will be resolved, it can be a host name or ipv4. + * The port will be resolved, it can be a port type or number. + * + * \param addr a string representing the destination address + * \param port a string representing the destination port + * \param recv_buff_size size in bytes for the recv buffer, 0 for automatic + * \param send_buff_size size in bytes for the send buffer, 0 for automatic + */ + static sptr make( + const std::string &addr, + const std::string &port, + size_t recv_buff_size = 0, + size_t send_buff_size = 0 + ); +}; + +}} //namespace + +#endif /* INCLUDED_UHD_TRANSPORT_UDP_ZERO_COPY_HPP */ diff --git a/host/include/uhd/transport/vrt_if_packet.hpp b/host/include/uhd/transport/vrt_if_packet.hpp new file mode 100644 index 000000000..51bd81bb1 --- /dev/null +++ b/host/include/uhd/transport/vrt_if_packet.hpp @@ -0,0 +1,106 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TRANSPORT_VRT_IF_PACKET_HPP +#define INCLUDED_UHD_TRANSPORT_VRT_IF_PACKET_HPP + +#include <uhd/config.hpp> +#include <boost/cstdint.hpp> +#include <cstddef> //size_t + +namespace uhd{ namespace transport{ + +namespace vrt{ + + //! The maximum number of 32-bit words in a vrt if packet header + static const size_t max_if_hdr_words32 = 7; //hdr+sid+cid+tsi+tsf + + /*! + * Definition for fields that can be packed into a vrt if header. + * The size fields are used for input and output depending upon + * the operation used (ie the pack or unpack function call). + */ + struct UHD_API if_packet_info_t{ + //packet type (pack only supports data) + enum packet_type_t { + PACKET_TYPE_DATA = 0x0, + PACKET_TYPE_EXTENSION = 0x1, + PACKET_TYPE_CONTEXT = 0x2 + } packet_type; + + //size fields + size_t num_payload_words32; //required in pack, derived in unpack + size_t num_header_words32; //derived in pack, derived in unpack + size_t num_packet_words32; //derived in pack, required in unpack + + //header fields + size_t packet_count; + bool sob, eob; + + //optional fields + bool has_sid; boost::uint32_t sid; + bool has_cid; boost::uint64_t cid; + bool has_tsi; boost::uint32_t tsi; + bool has_tsf; boost::uint64_t tsf; + bool has_tlr; boost::uint32_t tlr; + }; + + /*! + * Pack a vrt header from metadata (big endian format). + * \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 vrt header to metadata (big endian format). + * \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 vrt header from metadata (little endian format). + * \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 vrt header to metadata (little endian format). + * \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 vrt + +}} //namespace + +#endif /* INCLUDED_UHD_TRANSPORT_VRT_IF_PACKET_HPP */ diff --git a/host/include/uhd/transport/zero_copy.hpp b/host/include/uhd/transport/zero_copy.hpp new file mode 100644 index 000000000..513291b63 --- /dev/null +++ b/host/include/uhd/transport/zero_copy.hpp @@ -0,0 +1,223 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TRANSPORT_ZERO_COPY_HPP +#define INCLUDED_UHD_TRANSPORT_ZERO_COPY_HPP + +#include <uhd/config.hpp> +#include <uhd/utils/pimpl.hpp> +#include <boost/asio/buffer.hpp> +#include <boost/utility.hpp> +#include <boost/shared_ptr.hpp> + +namespace uhd{ namespace transport{ + + /*! + * A managed receive buffer: + * Contains a reference to transport-managed memory, + * and a method to release the memory after reading. + */ + class UHD_API managed_recv_buffer : boost::noncopyable{ + public: + typedef boost::shared_ptr<managed_recv_buffer> sptr; + + /*! + * Managed recv buffer destructor: + * Signal to the transport that we are done with the buffer. + * This should be called to release the buffer to the transport. + * After calling, the referenced memory should be considered invalid. + */ + virtual ~managed_recv_buffer(void) = 0; + + /*! + * Get the size of the underlying buffer. + * \return the number of bytes + */ + inline size_t size(void) const{ + return boost::asio::buffer_size(this->get()); + } + + /*! + * Get a pointer to the underlying buffer. + * \return a pointer into memory + */ + template <class T> inline T cast(void) const{ + return boost::asio::buffer_cast<T>(this->get()); + } + + private: + /*! + * Get a reference to the internal const buffer. + * The buffer has a reference to memory and a size. + * \return a boost asio const buffer + */ + virtual const boost::asio::const_buffer &get(void) const = 0; + }; + + /*! + * A managed send buffer: + * Contains a reference to transport-managed memory, + * and a method to release the memory after writing. + */ + class UHD_API managed_send_buffer : boost::noncopyable{ + public: + typedef boost::shared_ptr<managed_send_buffer> sptr; + + /*! + * Signal to the transport that we are done with the buffer. + * This should be called to commit the write to the transport object. + * After calling, the referenced memory should be considered invalid. + * \param num_bytes the number of bytes written into the buffer + * \return the number of bytes written, 0 for timeout, negative for error + */ + virtual ssize_t commit(size_t num_bytes) = 0; + + /*! + * Get the size of the underlying buffer. + * \return the number of bytes + */ + inline size_t size(void) const{ + return boost::asio::buffer_size(this->get()); + } + + /*! + * Get a pointer to the underlying buffer. + * \return a pointer into memory + */ + template <class T> inline T cast(void) const{ + return boost::asio::buffer_cast<T>(this->get()); + } + + private: + /*! + * Get a reference to the internal mutable buffer. + * The buffer has a reference to memory and a size. + * \return a boost asio mutable buffer + */ + virtual const boost::asio::mutable_buffer &get(void) const = 0; + }; + + /*! + * A zero-copy interface for transport objects. + * Provides a way to get send and receive buffers + * with memory managed by the transport object. + */ + class UHD_API zero_copy_if : boost::noncopyable{ + public: + typedef boost::shared_ptr<zero_copy_if> sptr; + + /*! + * Get a new receive buffer from this transport object. + * \return a managed buffer, or null sptr on timeout/error + */ + virtual managed_recv_buffer::sptr get_recv_buff(void) = 0; + + /*! + * Get the maximum number of receive frames: + * The maximum number of valid managed recv buffers, + * or the maximum number of frames in the ring buffer, + * depending upon the underlying implementation. + * \return number of frames + */ + virtual size_t get_num_recv_frames(void) const = 0; + + /*! + * Get a new send buffer from this transport object. + * \return a managed buffer, or null sptr on timeout/error + */ + virtual managed_send_buffer::sptr get_send_buff(void) = 0; + + /*! + * Get the maximum number of send frames: + * The maximum number of valid managed send buffers, + * or the maximum number of frames in the ring buffer, + * depending upon the underlying implementation. + * \return number of frames + */ + virtual size_t get_num_send_frames(void) const = 0; + + }; + + /*! + * A phony-zero-copy interface for transport objects that + * provides a zero-copy interface on top of copying transport. + * This interface implements the get managed recv buffer, + * the base class must implement the private recv method. + */ + class UHD_API phony_zero_copy_recv_if : public virtual zero_copy_if{ + public: + /*! + * Create a phony zero copy recv interface. + * \param max_buff_size max buffer size in bytes + */ + phony_zero_copy_recv_if(size_t max_buff_size); + + //! destructor + virtual ~phony_zero_copy_recv_if(void); + + /*! + * Get a new receive buffer from this transport object. + */ + managed_recv_buffer::sptr get_recv_buff(void); + + private: + /*! + * Perform a private copying recv. + * \param buff the buffer to write data into + * \return the number of bytes written to buff, 0 for timeout, negative for error + */ + virtual ssize_t recv(const boost::asio::mutable_buffer &buff) = 0; + + UHD_PIMPL_DECL(impl) _impl; + }; + + /*! + * A phony-zero-copy interface for transport objects that + * provides a zero-copy interface on top of copying transport. + * This interface implements the get managed send buffer, + * the base class must implement the private send method. + */ + class UHD_API phony_zero_copy_send_if : public virtual zero_copy_if{ + public: + /*! + * Create a phony zero copy send interface. + * \param max_buff_size max buffer size in bytes + */ + phony_zero_copy_send_if(size_t max_buff_size); + + //! destructor + virtual ~phony_zero_copy_send_if(void); + + /*! + * Get a new send buffer from this transport object. + */ + managed_send_buffer::sptr get_send_buff(void); + + private: + /*! + * Perform a private copying send. + * \param buff the buffer to read data from + * \return the number of bytes read from buff, 0 for timeout, negative for error + */ + virtual ssize_t send(const boost::asio::const_buffer &buff) = 0; + + UHD_PIMPL_DECL(impl) _impl; + }; + +}} //namespace + +#endif /* INCLUDED_UHD_TRANSPORT_ZERO_COPY_HPP */ diff --git a/host/include/uhd/types/CMakeLists.txt b/host/include/uhd/types/CMakeLists.txt new file mode 100644 index 000000000..dbce21c98 --- /dev/null +++ b/host/include/uhd/types/CMakeLists.txt @@ -0,0 +1,33 @@ +# +# Copyright 2010 Ettus Research LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + + +INSTALL(FILES + clock_config.hpp + device_addr.hpp + dict.hpp + io_type.hpp + mac_addr.hpp + metadata.hpp + otw_type.hpp + ranges.hpp + serial.hpp + stream_cmd.hpp + time_spec.hpp + tune_result.hpp + DESTINATION ${INCLUDE_DIR}/uhd/types +) diff --git a/host/include/uhd/types/clock_config.hpp b/host/include/uhd/types/clock_config.hpp new file mode 100644 index 000000000..9342fbb7b --- /dev/null +++ b/host/include/uhd/types/clock_config.hpp @@ -0,0 +1,51 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TYPES_CLOCK_CONFIG_HPP +#define INCLUDED_UHD_TYPES_CLOCK_CONFIG_HPP + +#include <uhd/config.hpp> + +namespace uhd{ + + /*! + * Clock configuration settings: + * The source for the 10MHz reference clock. + * The source and polarity for the PPS clock. + */ + struct UHD_API clock_config_t{ + enum ref_source_t { + REF_AUTO = 'a', //automatic (device specific) + REF_INT = 'i', //internal reference + REF_SMA = 's', //external sma port + REF_MIMO = 'm' //mimo cable (usrp2 only) + } ref_source; + enum pps_source_t { + PPS_INT = 'i', //there is no internal + PPS_SMA = 's', //external sma port + PPS_MIMO = 'm' //mimo cable (usrp2 only) + } pps_source; + enum pps_polarity_t { + PPS_NEG = 'n', //negative edge + PPS_POS = 'p' //positive edge + } pps_polarity; + clock_config_t(void); + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_CLOCK_CONFIG_HPP */ diff --git a/host/include/uhd/types/device_addr.hpp b/host/include/uhd/types/device_addr.hpp new file mode 100644 index 000000000..e359d9467 --- /dev/null +++ b/host/include/uhd/types/device_addr.hpp @@ -0,0 +1,72 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TYPES_DEVICE_ADDR_HPP +#define INCLUDED_UHD_TYPES_DEVICE_ADDR_HPP + +#include <uhd/config.hpp> +#include <uhd/types/dict.hpp> +#include <vector> +#include <string> + +namespace uhd{ + + /*! + * Mapping of key/value pairs for locating devices on the system. + * When left empty, the device discovery routines will search + * all available transports on the system (ethernet, usb...). + * + * To narrow down the discovery process to a particular device, + * specify a transport key/value pair specific to your device. + * - Ex, to find a usrp2: my_dev_addr["addr"] = [resolvable_hostname_or_ip] + * + * The device address can also be used to pass arguments into + * the transport layer control to set (for example) buffer sizes. + * + * An arguments string, is a way to represent a device address + * using a single string with delimiter characters. + * - Ex: addr=192.168.10.2 + * - Ex: addr=192.168.10.2, recv_buff_size=1e6 + */ + class UHD_API device_addr_t : public dict<std::string, std::string>{ + public: + /*! + * Create a device address from an args string. + * \param args the arguments string + */ + device_addr_t(const std::string &args = ""); + + /*! + * Convert a device address into a pretty print string. + * \return a printable string representing the device address + */ + std::string to_pp_string(void) const; + + /*! + * Convert the device address into an args string. + * The args string contains delimiter symbols. + * \return a string with delimiter markup + */ + std::string to_string(void) const; + }; + + //handy typedef for a vector of device addresses + typedef std::vector<device_addr_t> device_addrs_t; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_DEVICE_ADDR_HPP */ diff --git a/host/include/uhd/types/dict.hpp b/host/include/uhd/types/dict.hpp new file mode 100644 index 000000000..de96ea768 --- /dev/null +++ b/host/include/uhd/types/dict.hpp @@ -0,0 +1,161 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TYPES_DICT_HPP +#define INCLUDED_UHD_TYPES_DICT_HPP + +#include <uhd/config.hpp> +#include <boost/foreach.hpp> +#include <boost/format.hpp> +#include <boost/lexical_cast.hpp> +#include <stdexcept> +#include <typeinfo> +#include <vector> +#include <list> + +namespace uhd{ + + /*! + * A templated dictionary class with a python-like interface. + */ + template <typename Key, typename Val> class dict{ + public: + typedef std::pair<Key, Val> pair_t; + + /*! + * Create a new empty dictionary. + */ + dict(void){ + /* NOP */ + } + + /*! + * Input iterator constructor: + * Makes boost::assign::map_list_of work. + * \param first the begin iterator + * \param last the end iterator + */ + template <typename InputIterator> + dict(InputIterator first, InputIterator last){ + for(InputIterator it = first; it != last; it++){ + _map.push_back(*it); + } + } + + /*! + * Destroy this dict. + */ + ~dict(void){ + /* NOP */ + } + + /*! + * Get the number of elements in this dict. + * \return the number of elements + */ + std::size_t size(void) const{ + return _map.size(); + } + + /*! + * Get a list of the keys in this dict. + * Key order depends on insertion precedence. + * \return vector of keys + */ + const std::vector<Key> keys(void) const{ + std::vector<Key> keys; + BOOST_FOREACH(const pair_t &p, _map){ + keys.push_back(p.first); + } + return keys; + } + + /*! + * Get a list of the values in this dict. + * Value order depends on insertion precedence. + * \return vector of values + */ + const std::vector<Val> vals(void) const{ + std::vector<Val> vals; + BOOST_FOREACH(const pair_t &p, _map){ + vals.push_back(p.second); + } + return vals; + } + + /*! + * Does the dictionary contain this key? + * \param key the key to look for + * \return true if found + */ + bool has_key(const Key &key) const{ + BOOST_FOREACH(const pair_t &p, _map){ + if (p.first == key) return true; + } + return false; + } + + /*! + * Get a value for the given key if it exists. + * If the key is not found throw an error. + * \param key the key to look for + * \return the value at the key + * \throw an exception when not found + */ + const Val &operator[](const Key &key) const{ + BOOST_FOREACH(const pair_t &p, _map){ + if (p.first == key) return p.second; + } + throw std::invalid_argument(str(boost::format( + "key \"%s\" not found in dict(%s, %s)" + ) % boost::lexical_cast<std::string>(key) + % typeid(Key).name() % typeid(Val).name())); + } + + /*! + * Set a value for the given key, however, in reality + * it really returns a reference which can be assigned to. + * \param key the key to set to + * \return a reference to the value + */ + Val &operator[](const Key &key){ + BOOST_FOREACH(pair_t &p, _map){ + if (p.first == key) return p.second; + } + _map.push_back(std::make_pair(key, Val())); + return _map.back().second; + } + + /*! + * Pop an item out of the dictionary. + * \param key the item key + * \return the value of the item + * \throw an exception when not found + */ + Val pop(const Key &key){ + Val val = (*this)[key]; + _map.remove(pair_t(key, val)); + return val; + } + + private: + std::list<pair_t> _map; //private container + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_DICT_HPP */ diff --git a/host/include/uhd/types/io_type.hpp b/host/include/uhd/types/io_type.hpp new file mode 100644 index 000000000..5176374d6 --- /dev/null +++ b/host/include/uhd/types/io_type.hpp @@ -0,0 +1,70 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TYPES_IO_TYPE_HPP +#define INCLUDED_UHD_TYPES_IO_TYPE_HPP + +#include <uhd/config.hpp> + +namespace uhd{ + + /*! + * The Input/Output configuration struct: + * Used to specify the IO type with device send/recv. + */ + class UHD_API io_type_t{ + public: + + /*! + * Built in IO types known to the system. + */ + enum tid_t{ + CUSTOM_TYPE = '?', + COMPLEX_FLOAT32 = 'f', + COMPLEX_INT16 = 's', + COMPLEX_INT8 = 'b' + }; + + /*! + * The size of this io type in bytes. + */ + const size_t size; + + /*! + * The type id of this io type. + * Good for using with switch statements. + */ + const tid_t tid; + + /*! + * Create an io type from a built-in type id. + * \param tid a type id known to the system + */ + io_type_t(tid_t tid); + + /*! + * Create an io type from attributes. + * The tid will be set to custom. + * \param size the size in bytes + */ + io_type_t(size_t size); + + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_IO_TYPE_HPP */ diff --git a/host/include/uhd/types/mac_addr.hpp b/host/include/uhd/types/mac_addr.hpp new file mode 100644 index 000000000..0ced2e734 --- /dev/null +++ b/host/include/uhd/types/mac_addr.hpp @@ -0,0 +1,66 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TYPES_MAC_ADDR_HPP +#define INCLUDED_UHD_TYPES_MAC_ADDR_HPP + +#include <uhd/config.hpp> +#include <uhd/types/serial.hpp> +#include <string> + +namespace uhd{ + + /*! + * Wrapper for an ethernet mac address. + * Provides conversion between string and binary formats. + */ + class UHD_API mac_addr_t{ + public: + /*! + * Create a mac address a byte array. + * \param bytes a vector of bytes + * \return a new mac address + */ + static mac_addr_t from_bytes(const byte_vector_t &bytes); + + /*! + * Create a mac address from a string. + * \param mac_addr_str the string with delimiters + * \return a new mac address + */ + static mac_addr_t from_string(const std::string &mac_addr_str); + + /*! + * Get the byte representation of the mac address. + * \return a vector of bytes + */ + byte_vector_t to_bytes(void) const; + + /*! + * Get the string representation of this mac address. + * \return a string with delimiters + */ + std::string to_string(void) const; + + private: + mac_addr_t(const byte_vector_t &bytes); //private constructor + const byte_vector_t _bytes; //internal representation + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_MAC_ADDR_HPP */ diff --git a/host/include/uhd/types/metadata.hpp b/host/include/uhd/types/metadata.hpp new file mode 100644 index 000000000..65952941c --- /dev/null +++ b/host/include/uhd/types/metadata.hpp @@ -0,0 +1,152 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TYPES_METADATA_HPP +#define INCLUDED_UHD_TYPES_METADATA_HPP + +#include <uhd/config.hpp> +#include <boost/cstdint.hpp> +#include <uhd/types/time_spec.hpp> + +namespace uhd{ + + /*! + * RX metadata structure for describing sent IF data. + * Includes time specification, fragmentation flags, burst flags, and error codes. + * The receive routines will convert IF data headers into metadata. + */ + struct UHD_API rx_metadata_t{ + /*! + * Time specification: + * Set from timestamps on incoming data when provided. + */ + bool has_time_spec; + time_spec_t time_spec; + + /*! + * Fragmentation flag and offset: + * Similar to IPv4 fragmentation: http://en.wikipedia.org/wiki/IPv4#Fragmentation_and_reassembly + * More fragments is true when the input buffer has insufficient size to fit + * an entire received packet. More fragments will be false for the last fragment. + * The fragment offset is the sample number at the start of the receive buffer. + * For non-fragmented receives, the fragment offset should always be zero. + */ + bool more_fragments; + size_t fragment_offset; + + /*! + * Burst flags: + * Start of burst will be true for the first packet in the chain. + * End of burst will be true for the last packet in the chain. + */ + bool start_of_burst; + bool end_of_burst; + + /*! + * Error conditions: + * - none: no error associated with this metadata + * - timeout: no packet received, underlying code timed-out + * - late command: a stream command was issued in the past + * - broken chain: expected another stream command + * - overflow: an internal receive buffer has filled + * - bad packet: the buffer was unrecognizable as a vrt packet + * + * Note: When an overrun occurs in continuous streaming mode, + * the device will continue to send samples to the host. + * For other streaming modes, streaming will discontinue + * until the user issues a new stream command. + * + * Note: The metadata fields have meaning for the following error codes: + * - none + * - late command + * - broken chain + * - overflow + */ + enum error_code_t { + ERROR_CODE_NONE = 0x0, + ERROR_CODE_TIMEOUT = 0x1, + ERROR_CODE_LATE_COMMAND = 0x2, + ERROR_CODE_BROKEN_CHAIN = 0x4, + ERROR_CODE_OVERFLOW = 0x8, + ERROR_CODE_BAD_PACKET = 0xf + } error_code; + }; + + /*! + * TX metadata structure for describing received IF data. + * Includes time specification, and start and stop burst flags. + * The send routines will convert the metadata to IF data headers. + */ + struct UHD_API tx_metadata_t{ + /*! + * Time specification: + * Set has time spec to false to perform a send "now". + * Or, set to true, and fill in time spec for a send "at". + */ + bool has_time_spec; + time_spec_t time_spec; + + /*! + * Burst flags: + * Set start of burst to true for the first packet in the chain. + * Set end of burst to true for the last packet in the chain. + */ + bool start_of_burst; + bool end_of_burst; + + /*! + * The default constructor: + * Sets the fields to default values (flags set to false). + */ + tx_metadata_t(void); + }; + + /*! + * Async metadata structure for describing transmit related events. + */ + struct UHD_API async_metadata_t{ + //! The channel number in a mimo configuration + size_t channel; + + /*! + * Time specification: when the async event occurred. + */ + bool has_time_spec; + time_spec_t time_spec; + + /*! + * Event codes: + * - success: a packet was successfully transmitted + * - underflow: an internal send buffer has emptied + * - sequence error: packet loss between host and device + * - time error: packet had time that was late (or too early) + * - underflow in packet: underflow occurred inside a packet + * - sequence error in burst: packet loss within a burst + */ + enum event_code_t { + EVENT_CODE_SUCCESS = 0x1, + EVENT_CODE_UNDERFLOW = 0x2, + EVENT_CODE_SEQ_ERROR = 0x4, + EVENT_CODE_TIME_ERROR = 0x8, + EVENT_CODE_UNDERFLOW_IN_PACKET = 0x10, + EVENT_CODE_SEQ_ERROR_IN_BURST = 0x20 + } event_code; + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_METADATA_HPP */ diff --git a/host/include/uhd/types/otw_type.hpp b/host/include/uhd/types/otw_type.hpp new file mode 100644 index 000000000..8e3e65d78 --- /dev/null +++ b/host/include/uhd/types/otw_type.hpp @@ -0,0 +1,69 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TYPES_OTW_TYPE_HPP +#define INCLUDED_UHD_TYPES_OTW_TYPE_HPP + +#include <uhd/config.hpp> + +namespace uhd{ + + /*! + * Description for over-the-wire integers: + * The DSP units in the FPGA deal with signed 16-bit integers. + * The width and shift define the translation between OTW and DSP, + * defined by the following relation: otw_int = dsp_int >> shift + * + * Note: possible combinations of width, shift, and byteorder + * depend on the internals of the FPGA. Not all are supported! + */ + struct UHD_API otw_type_t{ + + /*! + * Width of an over-the-wire integer in bits. + */ + size_t width; //in bits + + /*! + * Shift of an over-the-wire integer in bits. + * otw_int = dsp_int >> shift + * dsp_int = otw_int << shift + */ + size_t shift; //in bits + + /*! + * Constants for byte order (borrowed from numpy's dtype) + */ + enum /*bo_t*/ { + BO_NATIVE = '=', + BO_LITTLE_ENDIAN = '<', + BO_BIG_ENDIAN = '>', + BO_NOT_APPLICABLE = '|' + } byteorder; + + /*! + * Get the sample size of this otw type. + * \return the size of a sample in bytes + */ + size_t get_sample_size(void) const; + + otw_type_t(void); + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_OTW_TYPE_HPP */ diff --git a/host/include/uhd/types/ranges.hpp b/host/include/uhd/types/ranges.hpp new file mode 100644 index 000000000..a2057d1c8 --- /dev/null +++ b/host/include/uhd/types/ranges.hpp @@ -0,0 +1,46 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TYPES_RANGES_HPP +#define INCLUDED_UHD_TYPES_RANGES_HPP + +#include <uhd/config.hpp> + +namespace uhd{ + + /*! + * The gain range struct describes possible gain settings. + * The mimumum gain, maximum gain, and step size are in dB. + */ + struct UHD_API gain_range_t{ + float min, max, step; + gain_range_t(float min = 0.0, float max = 0.0, float step = 0.0); + }; + + /*! + * The frequency range struct describes possible frequency settings. + * Because tuning is very granular (sub-Hz), step size is not listed. + * The mimumum frequency and maximum frequency are in Hz. + */ + struct UHD_API freq_range_t{ + double min, max; + freq_range_t(double min = 0.0, double max = 0.0); + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_RANGES_HPP */ diff --git a/host/include/uhd/types/serial.hpp b/host/include/uhd/types/serial.hpp new file mode 100644 index 000000000..c134725f5 --- /dev/null +++ b/host/include/uhd/types/serial.hpp @@ -0,0 +1,122 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TYPES_SERIAL_HPP +#define INCLUDED_UHD_TYPES_SERIAL_HPP + +#include <uhd/config.hpp> +#include <boost/cstdint.hpp> +#include <vector> + +namespace uhd{ + + /*! + * Byte vector typedef for passing data in and out of I2C interfaces. + */ + typedef std::vector<boost::uint8_t> byte_vector_t; + + /*! + * The i2c interface class: + * Provides i2c and eeprom functionality. + * A subclass should only have to implement the i2c routines. + * An eeprom implementation comes for free with the interface. + * + * The eeprom routines are implemented on top of i2c. + * The built in eeprom implementation only does single + * byte reads and byte writes over the i2c interface, + * so it should be portable across multiple eeproms. + * Override the eeprom routines if this is not acceptable. + */ + class UHD_API i2c_iface{ + public: + /*! + * Write bytes over the i2c. + * \param addr the address + * \param buf the vector of bytes + */ + virtual void write_i2c( + boost::uint8_t addr, + const byte_vector_t &buf + ) = 0; + + /*! + * Read bytes over the i2c. + * \param addr the address + * \param num_bytes number of bytes to read + * \return a vector of bytes + */ + virtual byte_vector_t read_i2c( + boost::uint8_t addr, + size_t num_bytes + ) = 0; + + /*! + * Write bytes to an eeprom. + * \param addr the address + * \param offset byte offset + * \param buf the vector of bytes + */ + virtual void write_eeprom( + boost::uint8_t addr, + boost::uint8_t offset, + const byte_vector_t &buf + ); + + /*! + * Read bytes from an eeprom. + * \param addr the address + * \param offset byte offset + * \param num_bytes number of bytes to read + * \return a vector of bytes + */ + virtual byte_vector_t read_eeprom( + boost::uint8_t addr, + boost::uint8_t offset, + size_t num_bytes + ); + }; + + /*! + * The SPI configuration struct: + * Used to configure a SPI transaction interface. + */ + struct UHD_API spi_config_t{ + /*! + * The edge type specifies when data is valid + * relative to the edge of the serial clock. + */ + enum edge_t{ + EDGE_RISE = 'r', + EDGE_FALL = 'f' + }; + + //! on what edge is the mosi data valid? + edge_t mosi_edge; + + //! on what edge is the miso data valid? + edge_t miso_edge; + + /*! + * Create a new spi config. + * \param edge the default edge for mosi and miso + */ + spi_config_t(edge_t edge = EDGE_RISE); + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_SERIAL_HPP */ diff --git a/host/include/uhd/types/stream_cmd.hpp b/host/include/uhd/types/stream_cmd.hpp new file mode 100644 index 000000000..41708e2e2 --- /dev/null +++ b/host/include/uhd/types/stream_cmd.hpp @@ -0,0 +1,64 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TYPES_STREAM_CMD_HPP +#define INCLUDED_UHD_TYPES_STREAM_CMD_HPP + +#include <uhd/config.hpp> +#include <uhd/types/time_spec.hpp> + +namespace uhd{ + + /*! + * Command struct for configuration and control of streaming: + * + * A stream command defines how the device sends samples to the host. + * Streaming is controlled by submitting a stream command to the rx dsp. + * Granular control over what the device streams to the host can be + * achieved through submission of multiple (carefully-crafted) commands. + * + * The mode parameter controls how streaming is issued to the device: + * - "Start continuous" tells the device to stream samples indefinitely. + * - "Stop continuous" tells the device to end continuous streaming. + * - "Num samps and done" tells the device to stream num samps and + * to not expect a future stream command for contiguous samples. + * - "Num samps and more" tells the device to stream num samps and + * to expect a future stream command for contiguous samples. + * + * The stream now parameter controls when the stream begins. + * When true, the device will begin streaming ASAP. When false, + * the device will begin streaming at a time specified by time_spec. + */ + struct UHD_API stream_cmd_t{ + + enum stream_mode_t { + STREAM_MODE_START_CONTINUOUS = 'a', + STREAM_MODE_STOP_CONTINUOUS = 'o', + STREAM_MODE_NUM_SAMPS_AND_DONE = 'd', + STREAM_MODE_NUM_SAMPS_AND_MORE = 'm' + } stream_mode; + size_t num_samps; + + bool stream_now; + time_spec_t time_spec; + + stream_cmd_t(const stream_mode_t &stream_mode); + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_STREAM_CMD_HPP */ diff --git a/host/include/uhd/types/time_spec.hpp b/host/include/uhd/types/time_spec.hpp new file mode 100644 index 000000000..59b85f4b7 --- /dev/null +++ b/host/include/uhd/types/time_spec.hpp @@ -0,0 +1,110 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TYPES_TIME_SPEC_HPP +#define INCLUDED_UHD_TYPES_TIME_SPEC_HPP + +#include <uhd/config.hpp> +#include <boost/operators.hpp> +#include <ctime> + +namespace uhd{ + + /*! + * A time_spec_t holds a seconds and a fractional seconds time value. + * Depending upon usage, the time_spec_t can represent absolute times, + * relative times, or time differences (between absolute times). + * + * The time_spec_t provides clock-domain independent time storage, + * but can convert fractional seconds to/from clock-domain specific units. + * + * The fractional seconds are stored as double precision floating point. + * This gives the fractional seconds enough precision to unambiguously + * specify a clock-tick/sample-count up to rates of several petahertz. + */ + class UHD_API time_spec_t : boost::additive<time_spec_t>, boost::totally_ordered<time_spec_t>{ + public: + + /*! + * Create a time_spec_t from a real-valued seconds count. + * \param secs the real-valued seconds count (default = 0) + */ + time_spec_t(double secs = 0); + + /*! + * Create a time_spec_t from whole and fractional seconds. + * \param full_secs the whole/integer seconds count + * \param frac_secs the fractional seconds count (default = 0) + */ + time_spec_t(time_t full_secs, double frac_secs = 0); + + /*! + * Create a time_spec_t from whole and fractional seconds. + * Translation from clock-domain specific units. + * \param full_secs the whole/integer seconds count + * \param tick_count the fractional seconds tick count + * \param tick_rate the number of ticks per second + */ + time_spec_t(time_t full_secs, size_t tick_count, double tick_rate); + + /*! + * Convert the fractional seconds to clock ticks. + * Translation into clock-domain specific units. + * \param tick_rate the number of ticks per second + * \return the fractional seconds tick count + */ + size_t get_tick_count(double tick_rate) const; + + /*! + * Get the time as a real-valued seconds count. + * Note: If this time_spec_t represents an absolute time, + * the precision of the fractional seconds may be lost. + * \return the real-valued seconds + */ + double get_real_secs(void) const; + + /*! + * Get the whole/integer part of the time in seconds. + * \return the whole/integer seconds + */ + time_t get_full_secs(void) const; + + /*! + * Get the fractional part of the time in seconds. + * \return the fractional seconds + */ + double get_frac_secs(void) const; + + //! Implement addable interface + time_spec_t &operator+=(const time_spec_t &); + + //! Implement subtractable interface + time_spec_t &operator-=(const time_spec_t &); + + //private time storage details + private: time_t _full_secs; double _frac_secs; + }; + + //! Implement equality_comparable interface + UHD_API bool operator==(const time_spec_t &, const time_spec_t &); + + //! Implement less_than_comparable interface + UHD_API bool operator<(const time_spec_t &, const time_spec_t &); + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_TIME_SPEC_HPP */ diff --git a/host/include/uhd/types/tune_result.hpp b/host/include/uhd/types/tune_result.hpp new file mode 100644 index 000000000..9eebc161a --- /dev/null +++ b/host/include/uhd/types/tune_result.hpp @@ -0,0 +1,48 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TYPES_TUNE_RESULT_HPP +#define INCLUDED_UHD_TYPES_TUNE_RESULT_HPP + +#include <uhd/config.hpp> +#include <string> + +namespace uhd{ + + /*! + * The tune result struct holds result of a 2-phase tuning: + * The struct hold the result of tuning the dboard as + * the target and actual intermediate frequency. + * The struct hold the result of tuning the DSP as + * the target and actual digital converter frequency. + */ + struct UHD_API tune_result_t{ + double target_inter_freq; + double actual_inter_freq; + double target_dsp_freq; + double actual_dsp_freq; + + /*! + * Create a pretty print string for this tune result struct. + * \return the printable string + */ + std::string to_pp_string(void) const; + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_TUNE_RESULT_HPP */ diff --git a/host/include/uhd/usrp/CMakeLists.txt b/host/include/uhd/usrp/CMakeLists.txt new file mode 100644 index 000000000..76ee24e5f --- /dev/null +++ b/host/include/uhd/usrp/CMakeLists.txt @@ -0,0 +1,44 @@ +# +# Copyright 2010 Ettus Research LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + + +INSTALL(FILES + #### props headers ### + codec_props.hpp + dboard_props.hpp + device_props.hpp + dsp_props.hpp + mboard_props.hpp + subdev_props.hpp + + #### dboard headers ### + dboard_base.hpp + dboard_eeprom.hpp + dboard_id.hpp + dboard_iface.hpp + dboard_manager.hpp + + ### utilities ### + subdev_spec.hpp + tune_helper.hpp + + ### interfaces ### + simple_usrp.hpp + mimo_usrp.hpp + + DESTINATION ${INCLUDE_DIR}/uhd/usrp +) diff --git a/host/include/uhd/usrp/codec_props.hpp b/host/include/uhd/usrp/codec_props.hpp new file mode 100644 index 000000000..ab09b1703 --- /dev/null +++ b/host/include/uhd/usrp/codec_props.hpp @@ -0,0 +1,42 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_USRP_CODEC_PROPS_HPP +#define INCLUDED_UHD_USRP_CODEC_PROPS_HPP + +#include <uhd/utils/props.hpp> + +namespace uhd{ namespace usrp{ + + /*! + * Possible device codec properties: + * A codec is expected to have a rate and gain elements. + * Other properties can be discovered through the others prop. + */ + enum codec_prop_t{ + CODEC_PROP_NAME = 'n', //ro, std::string + CODEC_PROP_OTHERS = 'o', //ro, prop_names_t + CODEC_PROP_GAIN_I = 'i', //rw, float + CODEC_PROP_GAIN_Q = 'q', //rw, float + CODEC_PROP_GAIN_RANGE = 'r', //ro, gain_range_t + CODEC_PROP_GAIN_NAMES = 'G' //ro, prop_names_t + }; + + +}} //namespace + +#endif /* INCLUDED_UHD_USRP_CODEC_PROPS_HPP */ diff --git a/host/include/uhd/usrp/dboard_base.hpp b/host/include/uhd/usrp/dboard_base.hpp new file mode 100644 index 000000000..9b75d791f --- /dev/null +++ b/host/include/uhd/usrp/dboard_base.hpp @@ -0,0 +1,117 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_USRP_DBOARD_BASE_HPP +#define INCLUDED_UHD_USRP_DBOARD_BASE_HPP + +#include <uhd/config.hpp> +#include <uhd/wax.hpp> +#include <uhd/utils/pimpl.hpp> +#include <boost/utility.hpp> +#include <boost/shared_ptr.hpp> +#include <uhd/usrp/dboard_id.hpp> +#include <uhd/usrp/dboard_iface.hpp> + +namespace uhd{ namespace usrp{ + +/*! + * A daughter board dboard_base class for all dboards. + * Only other dboard dboard_base classes should inherit this. + */ +class UHD_API dboard_base : boost::noncopyable{ +public: + typedef boost::shared_ptr<dboard_base> sptr; + /*! + * An opaque type for the dboard constructor args. + * Derived classes should pass the args into the base class, + * but should not deal with the internals of the args. + */ + typedef void * ctor_args_t; + + //structors + dboard_base(ctor_args_t); + virtual ~dboard_base(void); + + //interface + virtual void rx_get(const wax::obj &key, wax::obj &val) = 0; + virtual void rx_set(const wax::obj &key, const wax::obj &val) = 0; + virtual void tx_get(const wax::obj &key, wax::obj &val) = 0; + virtual void tx_set(const wax::obj &key, const wax::obj &val) = 0; + +protected: + std::string get_subdev_name(void); + dboard_iface::sptr get_iface(void); + dboard_id_t get_rx_id(void); + dboard_id_t get_tx_id(void); + +private: + UHD_PIMPL_DECL(impl) _impl; +}; + +/*! + * A xcvr daughter board implements rx and tx methods + * Sub classes for xcvr boards should inherit this. + */ +class UHD_API xcvr_dboard_base : public dboard_base{ +public: + /*! + * Create a new xcvr dboard object, override in subclasses. + */ + xcvr_dboard_base(ctor_args_t); + + virtual ~xcvr_dboard_base(void); +}; + +/*! + * A rx daughter board only implements rx methods. + * Sub classes for rx-only boards should inherit this. + */ +class UHD_API rx_dboard_base : public dboard_base{ +public: + /*! + * Create a new rx dboard object, override in subclasses. + */ + rx_dboard_base(ctor_args_t); + + virtual ~rx_dboard_base(void); + + //override here so the derived classes cannot + void tx_get(const wax::obj &key, wax::obj &val); + void tx_set(const wax::obj &key, const wax::obj &val); +}; + +/*! + * A tx daughter board only implements tx methods. + * Sub classes for rx-only boards should inherit this. + */ +class UHD_API tx_dboard_base : public dboard_base{ +public: + /*! + * Create a new rx dboard object, override in subclasses. + */ + tx_dboard_base(ctor_args_t); + + virtual ~tx_dboard_base(void); + + //override here so the derived classes cannot + void rx_get(const wax::obj &key, wax::obj &val); + void rx_set(const wax::obj &key, const wax::obj &val); +}; + +}} //namespace + +#endif /* INCLUDED_UHD_USRP_DBOARD_BASE_HPP */ diff --git a/host/include/uhd/usrp/dboard_eeprom.hpp b/host/include/uhd/usrp/dboard_eeprom.hpp new file mode 100644 index 000000000..108027b46 --- /dev/null +++ b/host/include/uhd/usrp/dboard_eeprom.hpp @@ -0,0 +1,60 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_USRP_DBOARD_EEPROM_HPP +#define INCLUDED_UHD_USRP_DBOARD_EEPROM_HPP + +#include <uhd/config.hpp> +#include <uhd/usrp/dboard_id.hpp> +#include <uhd/types/serial.hpp> +#include <string> + +namespace uhd{ namespace usrp{ + +struct UHD_API dboard_eeprom_t{ + /*! + * The dboard id that was read from eeprom or will be set to eeprom. + */ + dboard_id_t id; + + /*! + * Create a dboard eeprom struct from the bytes read out of eeprom. + * The constructor will parse out the dboard id from a vector of bytes. + * To be valid, the bytes vector should be at least num_bytes() long. + * If the parsing fails due to bad checksum or incomplete length, + * the dboard id in this struct will be set to dboard_id::NONE. + * \param bytes the vector of bytes + */ + dboard_eeprom_t(const uhd::byte_vector_t &bytes = uhd::byte_vector_t(0)); + + /*! + * Get the bytes that would be written to dboard eeprom. + * \return a vector of bytes + */ + uhd::byte_vector_t get_eeprom_bytes(void); + + /*! + * Get the number of bytes in the dboard eeprom segment. + * Use this value when reading out of the dboard eeprom. + * \return the number of bytes used by dboard eeprom + */ + static size_t num_bytes(void); +}; + +}} //namespace + +#endif /* INCLUDED_UHD_USRP_DBOARD_EEPROM_HPP */ diff --git a/host/include/uhd/usrp/dboard_id.hpp b/host/include/uhd/usrp/dboard_id.hpp new file mode 100644 index 000000000..4c45e4334 --- /dev/null +++ b/host/include/uhd/usrp/dboard_id.hpp @@ -0,0 +1,90 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_USRP_DBOARD_ID_HPP +#define INCLUDED_UHD_USRP_DBOARD_ID_HPP + +#include <uhd/config.hpp> +#include <boost/cstdint.hpp> +#include <boost/operators.hpp> +#include <string> + +namespace uhd{ namespace usrp{ + + class UHD_API dboard_id_t : boost::equality_comparable<dboard_id_t>{ + public: + /*! + * Create a dboard id from an integer. + * \param id the integer representation + */ + dboard_id_t(boost::uint16_t id = 0xffff); + + /*! + * Obtain a dboard id that represents no dboard. + * \return the dboard id with the 0xffff id. + */ + static dboard_id_t none(void); + + /*! + * Create a new dboard id from an integer representation. + * \param uint16 an unsigned 16 bit integer + * \return a new dboard id containing the integer + */ + static dboard_id_t from_uint16(boost::uint16_t uint16); + + /*! + * Get the dboard id represented as an integer. + * \return an unsigned 16 bit integer representation + */ + boost::uint16_t to_uint16(void) const; + + /*! + * Create a new dboard id from a string representation. + * If the string has a 0x prefix, it will be parsed as hex. + * \param string a numeric string, possibly hex + * \return a new dboard id containing the integer + */ + static dboard_id_t from_string(const std::string &string); + + /*! + * Get the dboard id represented as an integer. + * \return a hex string representation with 0x prefix + */ + std::string to_string(void) const; + + /*! + * Get the pretty print representation of this dboard id. + * \return a string with the dboard name and id number + */ + std::string to_pp_string(void) const; + + private: + boost::uint16_t _id; //internal representation + }; + + /*! + * Comparator operator overloaded for dboard ids. + * The boost::equality_comparable provides the !=. + * \param lhs the dboard id to the left of the operator + * \param rhs the dboard id to the right of the operator + * \return true when the dboard ids are equal + */ + UHD_API bool operator==(const dboard_id_t &lhs, const dboard_id_t &rhs); + +}} //namespace + +#endif /* INCLUDED_UHD_USRP_DBOARD_ID_HPP */ diff --git a/host/include/uhd/usrp/dboard_iface.hpp b/host/include/uhd/usrp/dboard_iface.hpp new file mode 100644 index 000000000..fc7ea3052 --- /dev/null +++ b/host/include/uhd/usrp/dboard_iface.hpp @@ -0,0 +1,218 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_USRP_DBOARD_IFACE_HPP +#define INCLUDED_UHD_USRP_DBOARD_IFACE_HPP + +#include <uhd/config.hpp> +#include <uhd/types/serial.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/cstdint.hpp> +#include <string> +#include <vector> + +namespace uhd{ namespace usrp{ + +/*! + * The daughter board dboard interface to be subclassed. + * A dboard instance interfaces with the mboard though this api. + * This interface provides i2c, spi, gpio, atr, aux dac/adc access. + * Each mboard should have a specially tailored iface for its dboard. + */ +class UHD_API dboard_iface{ +public: + typedef boost::shared_ptr<dboard_iface> sptr; + + //! tells the host which unit to use + enum unit_t{ + UNIT_RX = 'r', + UNIT_TX = 't' + }; + + //! possible atr registers + enum atr_reg_t{ + ATR_REG_IDLE = 'i', + ATR_REG_TX_ONLY = 't', + ATR_REG_RX_ONLY = 'r', + ATR_REG_FULL_DUPLEX = 'f' + }; + + //! aux dac selection enums (per unit) + enum aux_dac_t{ + AUX_DAC_A = 'a', + AUX_DAC_B = 'b', + AUX_DAC_C = 'c', + AUX_DAC_D = 'd' + }; + + //! aux adc selection enums (per unit) + enum aux_adc_t{ + AUX_ADC_A = 'a', + AUX_ADC_B = 'b' + }; + + /*! + * Get the motherboard name of the form: usrp1, usrp2... + * \return string representing the motherboard name + */ + virtual std::string get_mboard_name(void) = 0; + + /*! + * Write to an aux dac. + * + * \param unit which unit rx or tx + * \param which_dac the dac index 0, 1, 2, 3... + * \param value the value in volts + */ + virtual void write_aux_dac(unit_t unit, aux_dac_t which_dac, float value) = 0; + + /*! + * Read from an aux adc. + * + * \param unit which unit rx or tx + * \param which_adc the adc index 0, 1, 2, 3... + * \return the value in volts + */ + virtual float read_aux_adc(unit_t unit, aux_adc_t which_adc) = 0; + + /*! + * Set a daughterboard output pin control source. + * By default, the outputs are all GPIO controlled. + * + * \param unit which unit rx or tx + * \param value 16-bits, 0=GPIO controlled, 1=ATR controlled + */ + virtual void set_pin_ctrl(unit_t unit, boost::uint16_t value) = 0; + + /*! + * Set a daughterboard ATR register. + * + * \param unit which unit rx or tx + * \param reg which ATR register to set + * \param value 16-bits, 0=ATR output low, 1=ATR output high + */ + virtual void set_atr_reg(unit_t unit, atr_reg_t reg, boost::uint16_t value) = 0; + + /*! + * Set daughterboard GPIO data direction register. + * By default, the GPIO pins are all inputs. + * + * \param unit which unit rx or tx + * \param value 16-bits, 0=GPIO input, 1=GPIO output + */ + virtual void set_gpio_ddr(unit_t unit, boost::uint16_t value) = 0; + + /*! + * Read daughterboard GPIO pin values. + * + * \param unit which unit rx or tx + * \param value 16-bits, 0=GPIO output low, 1=GPIO output high + */ + virtual void write_gpio(unit_t unit, boost::uint16_t value) = 0; + + /*! + * Read daughterboard GPIO pin values. + * + * \param unit which unit rx or tx + * \return the value of the gpio unit + */ + virtual boost::uint16_t read_gpio(unit_t unit) = 0; + + /*! + * Write to an I2C peripheral. + * + * \param addr I2C bus address (7-bits) + * \param bytes the data to write + */ + virtual void write_i2c(boost::uint8_t addr, const byte_vector_t &bytes) = 0; + + /*! + * Read from an I2C peripheral. + * + * \param addr I2C bus address (7-bits) + * \param num_bytes number of bytes to read + * \return the data read if successful, else a zero length string. + */ + virtual byte_vector_t read_i2c(boost::uint8_t addr, size_t num_bytes) = 0; + + /*! + * Write data to SPI bus peripheral. + * + * \param unit which unit, rx or tx + * \param config configuration settings + * \param data the bits to write LSB first + * \param num_bits the number of bits in data + */ + virtual void write_spi( + unit_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits + ) = 0; + + /*! + * Read and write data to SPI bus peripheral. + * + * \param unit which unit, rx or tx + * \param config configuration settings + * \param data the bits to write LSB first + * \param num_bits the number of bits in data + * \return the data that was read + */ + virtual boost::uint32_t read_write_spi( + unit_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits + ) = 0; + + /*! + * Set the rate of a dboard clock. + * + * \param unit which unit rx or tx + * \param rate the clock rate in Hz + */ + virtual void set_clock_rate(unit_t unit, double rate) = 0; + + /*! + * Get the rate of a dboard clock. + * + * \param unit which unit rx or tx + * \return the clock rate in Hz + */ + virtual double get_clock_rate(unit_t unit) = 0; + + /*! + * Get a list of possible rates for the dboard clock. + * + * \param unit which unit rx or tx + * \return a list of clock rates in Hz + */ + virtual std::vector<double> get_clock_rates(unit_t unit) = 0; + + /*! + * Enable or disable a dboard clock. + * + * \param unit which unit rx or tx + * \param enb true for enabled + */ + virtual void set_clock_enabled(unit_t unit, bool enb) = 0; +}; + +}} //namespace + +#endif /* INCLUDED_UHD_USRP_DBOARD_IFACE_HPP */ diff --git a/host/include/uhd/usrp/dboard_manager.hpp b/host/include/uhd/usrp/dboard_manager.hpp new file mode 100644 index 000000000..e5831d4cf --- /dev/null +++ b/host/include/uhd/usrp/dboard_manager.hpp @@ -0,0 +1,96 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_USRP_DBOARD_MANAGER_HPP +#define INCLUDED_UHD_USRP_DBOARD_MANAGER_HPP + +#include <uhd/config.hpp> +#include <uhd/utils/props.hpp> +#include <uhd/usrp/dboard_base.hpp> +#include <uhd/usrp/dboard_id.hpp> +#include <boost/utility.hpp> +#include <boost/shared_ptr.hpp> + +namespace uhd{ namespace usrp{ + +/*! + * A daughter board subdev dboard_manager class. + * Create subdev instances for each subdev on a dboard. + * Provide wax::obj access to the subdevs inside. + */ +class UHD_API dboard_manager : boost::noncopyable{ +public: + typedef boost::shared_ptr<dboard_manager> sptr; + + //dboard constructor (each dboard should have a ::make with this signature) + typedef dboard_base::sptr(*dboard_ctor_t)(dboard_base::ctor_args_t); + + /*! + * Register a rx or tx dboard into the system. + * For single subdevice boards, omit subdev_names. + * \param dboard_id the dboard id (rx or tx) + * \param dboard_ctor the dboard constructor function pointer + * \param name the canonical name for the dboard represented + * \param subdev_names the names of the subdevs on this dboard + */ + static void register_dboard( + const dboard_id_t &dboard_id, + dboard_ctor_t dboard_ctor, + const std::string &name, + const prop_names_t &subdev_names = prop_names_t(1, "") + ); + + /*! + * Register an xcvr dboard into the system. + * For single subdevice boards, omit subdev_names. + * \param rx_dboard_id the rx unit dboard id + * \param tx_dboard_id the tx unit dboard id + * \param dboard_ctor the dboard constructor function pointer + * \param name the canonical name for the dboard represented + * \param subdev_names the names of the subdevs on this dboard + */ + static void register_dboard( + const dboard_id_t &rx_dboard_id, + const dboard_id_t &tx_dboard_id, + dboard_ctor_t dboard_ctor, + const std::string &name, + const prop_names_t &subdev_names = prop_names_t(1, "") + ); + + /*! + * Make a new dboard manager. + * \param rx_dboard_id the id of the rx dboard + * \param tx_dboard_id the id of the tx dboard + * \param iface the custom dboard interface + * \return an sptr to the new dboard manager + */ + static sptr make( + dboard_id_t rx_dboard_id, + dboard_id_t tx_dboard_id, + dboard_iface::sptr iface + ); + + //dboard manager interface + virtual prop_names_t get_rx_subdev_names(void) = 0; + virtual prop_names_t get_tx_subdev_names(void) = 0; + virtual wax::obj get_rx_subdev(const std::string &subdev_name) = 0; + virtual wax::obj get_tx_subdev(const std::string &subdev_name) = 0; +}; + +}} //namespace + +#endif /* INCLUDED_UHD_USRP_DBOARD_MANAGER_HPP */ diff --git a/host/include/uhd/usrp/dboard_props.hpp b/host/include/uhd/usrp/dboard_props.hpp new file mode 100644 index 000000000..aab6c31ce --- /dev/null +++ b/host/include/uhd/usrp/dboard_props.hpp @@ -0,0 +1,42 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_USRP_DBOARD_PROPS_HPP +#define INCLUDED_UHD_USRP_DBOARD_PROPS_HPP + +#include <uhd/utils/props.hpp> + +namespace uhd{ namespace usrp{ + + /*! + * Possible device dboard properties: + * A dboard has an id, one or more subdevices, and a codec. + * A dboard is considered to be unidirectional (RX or TX). + */ + enum dboard_prop_t{ + DBOARD_PROP_NAME = 'n', //ro, std::string + DBOARD_PROP_SUBDEV = 's', //ro, wax::obj + DBOARD_PROP_SUBDEV_NAMES = 'S', //ro, prop_names_t + DBOARD_PROP_DBOARD_ID = 'i', //rw, dboard_id_t + DBOARD_PROP_DBOARD_IFACE = 'f', //ro, dboard_iface::sptr + DBOARD_PROP_CODEC = 'c', //ro, wax::obj + DBOARD_PROP_GAIN_GROUP = 'g' //ro, gain_group + }; + +}} //namespace + +#endif /* INCLUDED_UHD_USRP_DBOARD_PROPS_HPP */ diff --git a/host/include/uhd/usrp/device_props.hpp b/host/include/uhd/usrp/device_props.hpp new file mode 100644 index 000000000..346eec179 --- /dev/null +++ b/host/include/uhd/usrp/device_props.hpp @@ -0,0 +1,39 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_USRP_DEVICE_PROPS_HPP +#define INCLUDED_UHD_USRP_DEVICE_PROPS_HPP + +#include <uhd/utils/props.hpp> + +namespace uhd{ namespace usrp{ + + /*! + * Possible device properties: + * In general, a device will have a single mboard. + * In certain mimo applications, multiple boards + * will be present in the interface for configuration. + */ + enum device_prop_t{ + DEVICE_PROP_NAME = 'n', //ro, std::string + DEVICE_PROP_MBOARD = 'm', //ro, wax::obj + DEVICE_PROP_MBOARD_NAMES = 'M' //ro, prop_names_t + }; + +}} //namespace + +#endif /* INCLUDED_UHD_USRP_DEVICE_PROPS_HPP */ diff --git a/host/include/uhd/usrp/dsp_props.hpp b/host/include/uhd/usrp/dsp_props.hpp new file mode 100644 index 000000000..75d8c0a60 --- /dev/null +++ b/host/include/uhd/usrp/dsp_props.hpp @@ -0,0 +1,49 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_USRP_DSP_PROPS_HPP +#define INCLUDED_UHD_USRP_DSP_PROPS_HPP + +#include <uhd/utils/props.hpp> + +namespace uhd{ namespace usrp{ + + /*! + * Possible device dsp properties: + * A dsp is a black box fpga component found between + * the over-the-wire data and the codec pins. + * + * The host rate can be modified to control resampling. + * Resampling can take the form of decimation, interpolation, + * or more complex fractional resampling techniques. + * As usual, read back the host rate after setting it + * to get the actual rate that was set (implementation dependent). + * + * A dsp can also shift the digital stream in frequency. + * Set the shift property and read it back to get actual shift. + */ + enum dsp_prop_t{ + DSP_PROP_NAME = 'n', //ro, std::string + DSP_PROP_OTHERS = 'o', //ro, prop_names_t + DSP_PROP_FREQ_SHIFT = 'f', //rw, double Hz + DSP_PROP_CODEC_RATE = 'c', //ro, double Sps + DSP_PROP_HOST_RATE = 'h' //rw, double Sps + }; + +}} //namespace + +#endif /* INCLUDED_UHD_USRP_DSP_PROPS_HPP */ diff --git a/host/include/uhd/usrp/mboard_props.hpp b/host/include/uhd/usrp/mboard_props.hpp new file mode 100644 index 000000000..0f250f439 --- /dev/null +++ b/host/include/uhd/usrp/mboard_props.hpp @@ -0,0 +1,52 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_USRP_MBOARD_PROPS_HPP +#define INCLUDED_UHD_USRP_MBOARD_PROPS_HPP + +#include <uhd/utils/props.hpp> + +namespace uhd{ namespace usrp{ + + /*! + * Possible device mboard properties: + * The general mboard properties are listed below. + * Custom properties can be identified with a string + * and discovered though the others property. + */ + enum mboard_prop_t{ + MBOARD_PROP_NAME = 'n', //ro, std::string + MBOARD_PROP_OTHERS = 'o', //ro, prop_names_t + MBOARD_PROP_RX_DSP = 'd', //ro, wax::obj + MBOARD_PROP_RX_DSP_NAMES = 'D', //ro, prop_names_t + MBOARD_PROP_TX_DSP = 'u', //ro, wax::obj + MBOARD_PROP_TX_DSP_NAMES = 'U', //ro, prop_names_t + MBOARD_PROP_RX_DBOARD = 'e', //ro, wax::obj + MBOARD_PROP_RX_DBOARD_NAMES = 'E', //ro, prop_names_t + MBOARD_PROP_TX_DBOARD = 'v', //ro, wax::obj + MBOARD_PROP_TX_DBOARD_NAMES = 'V', //ro, prop_names_t + MBOARD_PROP_RX_SUBDEV_SPEC = 'r', //rw, subdev_spec_t + MBOARD_PROP_TX_SUBDEV_SPEC = 'R', //rw, subdev_spec_t + MBOARD_PROP_CLOCK_CONFIG = 'C', //rw, clock_config_t + MBOARD_PROP_TIME_NOW = 't', //rw, time_spec_t + MBOARD_PROP_TIME_NEXT_PPS = 'T', //wo, time_spec_t + MBOARD_PROP_STREAM_CMD = 's' //wo, stream_cmd_t + }; + +}} //namespace + +#endif /* INCLUDED_UHD_USRP_MBOARD_PROPS_HPP */ diff --git a/host/include/uhd/usrp/mimo_usrp.hpp b/host/include/uhd/usrp/mimo_usrp.hpp new file mode 100644 index 000000000..10a404059 --- /dev/null +++ b/host/include/uhd/usrp/mimo_usrp.hpp @@ -0,0 +1,180 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_USRP_MIMO_USRP_HPP +#define INCLUDED_UHD_USRP_MIMO_USRP_HPP + +#include <uhd/config.hpp> +#include <uhd/device.hpp> +#include <uhd/types/ranges.hpp> +#include <uhd/types/stream_cmd.hpp> +#include <uhd/types/clock_config.hpp> +#include <uhd/types/tune_result.hpp> +#include <uhd/usrp/subdev_spec.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/utility.hpp> +#include <vector> + +namespace uhd{ namespace usrp{ + +/*! + * The MIMO USRP device class: + * A mimo usrp facilitates ease-of-use for multi-usrp scenarios. + * The wrapper provides convenience functions to control the group + * of underlying devices as if they consisted of a single device. + */ +class UHD_API mimo_usrp : boost::noncopyable{ +public: + typedef boost::shared_ptr<mimo_usrp> sptr; + + /*! + * Make a new mimo usrp from the device address. + * \param dev_addr the device address + * \return a new mimo usrp object + */ + static sptr make(const device_addr_t &dev_addr); + + /*! + * Get the underlying device object. + * This is needed to get access to the streaming API and properties. + * \return the device object within this simple usrp + */ + virtual device::sptr get_device(void) = 0; + + /*! + * Get a printable name for this mimo usrp. + * \return a printable string + */ + virtual std::string get_pp_string(void) = 0; + + /*! + * Get the number of channels in this mimo configuration. + * The number of rx channels == the number of tx channels. + * \return the number of channels + */ + virtual size_t get_num_channels(void) = 0; + + /******************************************************************* + * Misc + ******************************************************************/ + /*! + * Gets the current time in the usrp time registers. + * \return a timespec representing current usrp time + */ + virtual time_spec_t get_time_now(void) = 0; + + /*! + * Set the time registers on the usrp at the next pps tick. + * The values will not be latched in until the pulse occurs. + * It is recommended that the user sleep(1) after calling to ensure + * that the time registers will be in a known state prior to use. + * This call works across all mboards in the mimo configuration. + * + * Note: Because this call sets the time on the "next" pps, + * the seconds in the time spec should be current seconds + 1. + * + * \param time_spec the time to latch into the usrp device + */ + virtual void set_time_next_pps(const time_spec_t &time_spec) = 0; + + /*! + * Synchronize the times across all motherboards in this configuration. + * Use this method to sync the times when the edge of the PPS is unknown. + * + * Ex: Host machine is not attached to serial port of GPSDO + * and can therefore not query the GPSDO for the PPS edge. + * + * This is a 3-step process, and will take at most 3 seconds to complete. + * Upon completion, the times will be synchronized to the time provided. + * + * - Step1: set the time at the next pps (potential race condition) + * - Step2: wait for the seconds to rollover to catch the pps edge + * - Step3: set the time at the next pps (synchronous for all boards) + * + * \param time_spec the time to latch into the usrp device + */ + virtual void set_time_unknown_pps(const time_spec_t &time_spec) = 0; + + /*! + * Issue a stream command to the usrp device. + * This tells the usrp to send samples into the host. + * See the documentation for stream_cmd_t for more info. + * \param stream_cmd the stream command to issue + */ + virtual void issue_stream_cmd(const stream_cmd_t &stream_cmd) = 0; + + /******************************************************************* + * RX methods + ******************************************************************/ + virtual void set_rx_subdev_spec(size_t chan, const uhd::usrp::subdev_spec_t &spec) = 0; + virtual uhd::usrp::subdev_spec_t get_rx_subdev_spec(size_t chan) = 0; + + virtual void set_rx_rate_all(double rate) = 0; + virtual double get_rx_rate_all(void) = 0; + + virtual tune_result_t set_rx_freq(size_t chan, double freq) = 0; + virtual tune_result_t set_rx_freq(size_t chan, double freq, double lo_off) = 0; + virtual double get_rx_freq(size_t chan) = 0; + virtual freq_range_t get_rx_freq_range(size_t chan) = 0; + + virtual void set_rx_gain(size_t chan, float gain) = 0; + virtual float get_rx_gain(size_t chan) = 0; + virtual gain_range_t get_rx_gain_range(size_t chan) = 0; + + virtual void set_rx_antenna(size_t chan, const std::string &ant) = 0; + virtual std::string get_rx_antenna(size_t chan) = 0; + virtual std::vector<std::string> get_rx_antennas(size_t chan) = 0; + + virtual bool get_rx_lo_locked(size_t chan) = 0; + + /*! + * Read the RSSI value from a usrp device. + * Or throw if the dboard does not support an RSSI readback. + * \param chan which mimo channel 0 to N-1 + * \return the rssi in dB + */ + virtual float read_rssi(size_t chan) = 0; + + /******************************************************************* + * TX methods + ******************************************************************/ + virtual void set_tx_subdev_spec(size_t chan, const uhd::usrp::subdev_spec_t &spec) = 0; + virtual uhd::usrp::subdev_spec_t get_tx_subdev_spec(size_t chan) = 0; + + virtual void set_tx_rate_all(double rate) = 0; + virtual double get_tx_rate_all(void) = 0; + + virtual tune_result_t set_tx_freq(size_t chan, double freq) = 0; + virtual tune_result_t set_tx_freq(size_t chan, double freq, double lo_off) = 0; + virtual double get_tx_freq(size_t chan) = 0; + virtual freq_range_t get_tx_freq_range(size_t chan) = 0; + + virtual void set_tx_gain(size_t chan, float gain) = 0; + virtual float get_tx_gain(size_t chan) = 0; + virtual gain_range_t get_tx_gain_range(size_t chan) = 0; + + virtual void set_tx_antenna(size_t chan, const std::string &ant) = 0; + virtual std::string get_tx_antenna(size_t chan) = 0; + virtual std::vector<std::string> get_tx_antennas(size_t chan) = 0; + + virtual bool get_tx_lo_locked(size_t chan) = 0; + +}; + +}} + +#endif /* INCLUDED_UHD_USRP_MIMO_USRP_HPP */ diff --git a/host/include/uhd/usrp/simple_usrp.hpp b/host/include/uhd/usrp/simple_usrp.hpp new file mode 100644 index 000000000..4da63c929 --- /dev/null +++ b/host/include/uhd/usrp/simple_usrp.hpp @@ -0,0 +1,166 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_USRP_SIMPLE_USRP_HPP +#define INCLUDED_UHD_USRP_SIMPLE_USRP_HPP + +#include <uhd/config.hpp> +#include <uhd/device.hpp> +#include <uhd/types/ranges.hpp> +#include <uhd/types/stream_cmd.hpp> +#include <uhd/types/clock_config.hpp> +#include <uhd/types/tune_result.hpp> +#include <uhd/usrp/subdev_spec.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/utility.hpp> +#include <vector> + +namespace uhd{ namespace usrp{ + +/*! + * The simple USRP device class: + * A simple usrp facilitates ease-of-use for most use-case scenarios. + * The wrapper provides convenience functions to tune the devices + * as well as to set the dboard gains, antennas, and other properties. + */ +class UHD_API simple_usrp : boost::noncopyable{ +public: + typedef boost::shared_ptr<simple_usrp> sptr; + + /*! + * Make a new simple usrp from the device address. + * \param dev_addr the device address + * \return a new simple usrp object + */ + static sptr make(const device_addr_t &dev_addr); + + /*! + * Get the underlying device object. + * This is needed to get access to the streaming API and properties. + * \return the device object within this simple usrp + */ + virtual device::sptr get_device(void) = 0; + + /*! + * Get a printable name for this simple usrp. + * \return a printable string + */ + virtual std::string get_pp_string(void) = 0; + + /******************************************************************* + * Misc + ******************************************************************/ + /*! + * Gets the current time in the usrp time registers. + * \return a timespec representing current usrp time + */ + virtual time_spec_t get_time_now(void) = 0; + + /*! + * Sets the time registers on the usrp immediately. + * \param time_spec the time to latch into the usrp device + */ + virtual void set_time_now(const time_spec_t &time_spec) = 0; + + /*! + * Set the time registers on the usrp at the next pps tick. + * The values will not be latched in until the pulse occurs. + * It is recommended that the user sleep(1) after calling to ensure + * that the time registers will be in a known state prior to use. + * + * Note: Because this call sets the time on the "next" pps, + * the seconds in the time spec should be current seconds + 1. + * + * \param time_spec the time to latch into the usrp device + */ + virtual void set_time_next_pps(const time_spec_t &time_spec) = 0; + + /*! + * Issue a stream command to the usrp device. + * This tells the usrp to send samples into the host. + * See the documentation for stream_cmd_t for more info. + * \param stream_cmd the stream command to issue + */ + virtual void issue_stream_cmd(const stream_cmd_t &stream_cmd) = 0; + + /*! + * Set the clock configuration for the usrp device. + * This tells the usrp how to get a 10Mhz reference and PPS clock. + * See the documentation for clock_config_t for more info. + * \param clock_config the clock configuration to set + */ + virtual void set_clock_config(const clock_config_t &clock_config) = 0; + + /******************************************************************* + * RX methods + ******************************************************************/ + virtual void set_rx_subdev_spec(const uhd::usrp::subdev_spec_t &spec) = 0; + virtual uhd::usrp::subdev_spec_t get_rx_subdev_spec(void) = 0; + + virtual void set_rx_rate(double rate) = 0; + virtual double get_rx_rate(void) = 0; + + virtual tune_result_t set_rx_freq(double freq) = 0; + virtual tune_result_t set_rx_freq(double freq, double lo_off) = 0; + virtual double get_rx_freq(void) = 0; + virtual freq_range_t get_rx_freq_range(void) = 0; + + virtual void set_rx_gain(float gain) = 0; + virtual float get_rx_gain(void) = 0; + virtual gain_range_t get_rx_gain_range(void) = 0; + + virtual void set_rx_antenna(const std::string &ant) = 0; + virtual std::string get_rx_antenna(void) = 0; + virtual std::vector<std::string> get_rx_antennas(void) = 0; + + virtual bool get_rx_lo_locked(void) = 0; + + /*! + * Read the RSSI value from a usrp device. + * Or throw if the dboard does not support an RSSI readback. + * \return the rssi in dB + */ + virtual float read_rssi(void) = 0; + + /******************************************************************* + * TX methods + ******************************************************************/ + virtual void set_tx_subdev_spec(const uhd::usrp::subdev_spec_t &spec) = 0; + virtual uhd::usrp::subdev_spec_t get_tx_subdev_spec(void) = 0; + + virtual void set_tx_rate(double rate) = 0; + virtual double get_tx_rate(void) = 0; + + virtual tune_result_t set_tx_freq(double freq) = 0; + virtual tune_result_t set_tx_freq(double freq, double lo_off) = 0; + virtual double get_tx_freq(void) = 0; + virtual freq_range_t get_tx_freq_range(void) = 0; + + virtual void set_tx_gain(float gain) = 0; + virtual float get_tx_gain(void) = 0; + virtual gain_range_t get_tx_gain_range(void) = 0; + + virtual void set_tx_antenna(const std::string &ant) = 0; + virtual std::string get_tx_antenna(void) = 0; + virtual std::vector<std::string> get_tx_antennas(void) = 0; + + virtual bool get_tx_lo_locked(void) = 0; +}; + +}} + +#endif /* INCLUDED_UHD_USRP_SIMPLE_USRP_HPP */ diff --git a/host/include/uhd/usrp/subdev_props.hpp b/host/include/uhd/usrp/subdev_props.hpp new file mode 100644 index 000000000..cd07cb7a8 --- /dev/null +++ b/host/include/uhd/usrp/subdev_props.hpp @@ -0,0 +1,63 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_USRP_SUBDEV_PROPS_HPP +#define INCLUDED_UHD_USRP_SUBDEV_PROPS_HPP + +#include <uhd/utils/props.hpp> + +namespace uhd{ namespace usrp{ + + /*! + * Possible subdev connection types: + * + * A complex subdevice is physically connected to both channels, + * which may be connected in one of two ways: IQ or QI (swapped). + * + * A real subdevice is only physically connected one channel, + * either only the I channel or only the Q channel. + */ + enum subdev_conn_t{ + SUBDEV_CONN_COMPLEX_IQ = 'C', + SUBDEV_CONN_COMPLEX_QI = 'c', + SUBDEV_CONN_REAL_I = 'R', + SUBDEV_CONN_REAL_Q = 'r' + }; + + /*! + * Possible device subdev properties + */ + enum subdev_prop_t{ + SUBDEV_PROP_NAME = 'n', //ro, std::string + SUBDEV_PROP_OTHERS = 'o', //ro, prop_names_t + SUBDEV_PROP_GAIN = 'g', //rw, float + SUBDEV_PROP_GAIN_RANGE = 'r', //ro, gain_range_t + SUBDEV_PROP_GAIN_NAMES = 'G', //ro, prop_names_t + SUBDEV_PROP_FREQ = 'f', //rw, double + SUBDEV_PROP_FREQ_RANGE = 'F', //ro, freq_range_t + SUBDEV_PROP_ANTENNA = 'a', //rw, std::string + SUBDEV_PROP_ANTENNA_NAMES = 'A', //ro, prop_names_t + SUBDEV_PROP_LO_LOCKED = 'L', //ro, bool + SUBDEV_PROP_CONNECTION = 'c', //ro, subdev_conn_t + SUBDEV_PROP_USE_LO_OFFSET = 'l', //ro, bool + SUBDEV_PROP_RSSI = 'R', //ro, float + SUBDEV_PROP_BANDWIDTH = 'B' //rw, double + }; + +}} //namespace + +#endif /* INCLUDED_UHD_USRP_SUBDEV_PROPS_HPP */ diff --git a/host/include/uhd/usrp/subdev_spec.hpp b/host/include/uhd/usrp/subdev_spec.hpp new file mode 100644 index 000000000..4d8f03b77 --- /dev/null +++ b/host/include/uhd/usrp/subdev_spec.hpp @@ -0,0 +1,95 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_USRP_SUBDEV_SPEC_HPP +#define INCLUDED_UHD_USRP_SUBDEV_SPEC_HPP + +#include <uhd/config.hpp> +#include <vector> +#include <string> + +namespace uhd{ namespace usrp{ + + /*! + * A subdevice specification (daughterboard, subdevice) name pairing. + */ + struct UHD_API subdev_spec_pair_t{ + //! The daughterboard name + std::string db_name; + + //! The subdevice name + std::string sd_name; + + /*! + * Create a new subdevice specification pair from dboard and subdev names. + * \param db_name the name of a daughterboard slot + * \param sd_name the name of a subdevice on that daughterboard + */ + subdev_spec_pair_t( + const std::string &db_name, const std::string &sd_name + ); + }; + + /*! + * A list of (daughterboard name, subdevice name) pairs: + * + * A subdevice specification represents a list of subdevices on a motherboard. + * The subdevices specified may span across multiple daughterboards; + * Hence the need for a subdevice specification over a simple list of strings. + * Typically, the user will pass a RX or TX subdevice specification into the API, + * and the implementation will infer the channel configuration from the specification. + * + * The subdevice specification can be represented as a markup-string. + * The markup-string is a whitespace separated list of dboard:subdev pairs. + * The "dboard:" part is optional on boards with only one daughterboard slot. + * The first pair represents the subdevice for channel zero, + * the second pair represents the subdevice for channel one, and so on. + * + * Examples: + * - Use subdevice AB on daughterboard A (USRP1): "A:AB" + * - Use subdevice A on daughterboard A for channel zero and subdevice A on daughterboard B for channel one (USRP1): "A:A B:A" + * - Use subdevice AB (USRP2): "AB" or ":AB" + * + * An empty subdevice specification can be used to automatically + * select the first subdevice on the first present daughterboard. + */ + class UHD_API subdev_spec_t : public std::vector<subdev_spec_pair_t>{ + public: + + /*! + * Create a subdev specification from a markup string. + * \param markup the markup string + */ + subdev_spec_t(const std::string &markup = ""); + + /*! + * Convert a subdev specification into a pretty print string. + * \return a printable string representing the subdev specification + */ + std::string to_pp_string(void) const; + + /*! + * Convert the subdevice specification into a markup string. + * The markup string contains the delimiter symbols. + * \return a string with delimiter markup + */ + std::string to_string(void) const; + }; + +}} + +#endif /* INCLUDED_UHD_USRP_SUBDEV_SPEC_HPP */ diff --git a/host/include/uhd/usrp/tune_helper.hpp b/host/include/uhd/usrp/tune_helper.hpp new file mode 100644 index 000000000..df3907b3e --- /dev/null +++ b/host/include/uhd/usrp/tune_helper.hpp @@ -0,0 +1,99 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_USRP_TUNE_HELPER_HPP +#define INCLUDED_UHD_USRP_TUNE_HELPER_HPP + +#include <uhd/config.hpp> +#include <uhd/wax.hpp> +#include <uhd/types/tune_result.hpp> + +namespace uhd{ namespace usrp{ + + /*! + * Tune a rx chain to the desired frequency: + * The IF of the subdevice is set as close as possible to + * the given target frequency + the LO offset (when applicable). + * The ddc cordic is setup to bring the IF down to baseband. + * \param subdev the dboard subdevice object with properties + * \param ddc the mboard dsp object with properties + * \param target_freq the desired center frequency + * \param lo_offset an offset for the subdevice IF from center + * \return a tune result struct + */ + UHD_API tune_result_t tune_rx_subdev_and_dsp( + wax::obj subdev, wax::obj ddc, + double target_freq, double lo_offset + ); + + /*! + * Tune a rx chain to the desired frequency: + * Same as the above, except the LO offset + * is calculated based on the subdevice and BW. + */ + UHD_API tune_result_t tune_rx_subdev_and_dsp( + wax::obj subdev, wax::obj ddc, double target_freq + ); + + /*! + * Calculate the overall frequency from the combination of dboard IF and DDC shift. + * \param subdev the dboard subdevice object with properties + * \param ddc the mboard dsp object with properties + * \return the overall tune frequency of the system in Hz + */ + UHD_API double derive_freq_from_rx_subdev_and_dsp( + wax::obj subdev, wax::obj ddc + ); + + /*! + * Tune a tx chain to the desired frequency: + * The IF of the subdevice is set as close as possible to + * the given target frequency + the LO offset (when applicable). + * The duc cordic is setup to bring the baseband up to IF. + * \param subdev the dboard subdevice object with properties + * \param duc the mboard dsp object with properties + * \param target_freq the desired center frequency + * \param lo_offset an offset for the subdevice IF from center + * \return a tune result struct + */ + UHD_API tune_result_t tune_tx_subdev_and_dsp( + wax::obj subdev, wax::obj duc, + double target_freq, double lo_offset + ); + + /*! + * Tune a tx chain to the desired frequency: + * Same as the above, except the LO offset + * is calculated based on the subdevice and BW. + */ + UHD_API tune_result_t tune_tx_subdev_and_dsp( + wax::obj subdev, wax::obj duc, double target_freq + ); + + /*! + * Calculate the overall frequency from the combination of dboard IF and DUC shift. + * \param subdev the dboard subdevice object with properties + * \param duc the mboard dsp object with properties + * \return the overall tune frequency of the system in Hz + */ + UHD_API double derive_freq_from_tx_subdev_and_dsp( + wax::obj subdev, wax::obj duc + ); + +}} + +#endif /* INCLUDED_UHD_USRP_TUNE_HELPER_HPP */ diff --git a/host/include/uhd/utils/CMakeLists.txt b/host/include/uhd/utils/CMakeLists.txt new file mode 100644 index 000000000..ef8e64ce0 --- /dev/null +++ b/host/include/uhd/utils/CMakeLists.txt @@ -0,0 +1,33 @@ +# +# Copyright 2010 Ettus Research LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +INSTALL(FILES + algorithm.hpp + assert.hpp + assert.ipp + byteswap.hpp + byteswap.ipp + exception.hpp + gain_group.hpp + pimpl.hpp + props.hpp + safe_main.hpp + static.hpp + thread_priority.hpp + warning.hpp + DESTINATION ${INCLUDE_DIR}/uhd/utils +) diff --git a/host/include/uhd/utils/algorithm.hpp b/host/include/uhd/utils/algorithm.hpp new file mode 100644 index 000000000..1b5eacfa9 --- /dev/null +++ b/host/include/uhd/utils/algorithm.hpp @@ -0,0 +1,152 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_UTILS_ALGORITHM_HPP +#define INCLUDED_UHD_UTILS_ALGORITHM_HPP + +#include <algorithm> +#include <boost/range/begin.hpp> +#include <boost/range/end.hpp> +#include <boost/range/size.hpp> + +/*! \file algorithm.hpp + * Useful templated functions and classes that I like to pretend are part of stl. + * Many of the range wrapper functions come with recent versions of boost (1.43). + */ +namespace std{ + + /*! + * A wrapper around std::copy that takes ranges instead of iterators. + * + * Copy the elements of the source range into the destination range. + * The destination range should be at least as large as the source range. + * + * \param src the range of elements to copy from + * \param dst the range of elements to be filled + */ + template<typename RangeSrc, typename RangeDst> inline + void copy(const RangeSrc &src, RangeDst &dst){ + std::copy(boost::begin(src), boost::end(src), boost::begin(dst)); + } + + /*! + * A wrapper around std::sort that takes a range instead of an iterator. + * + * The elements are sorted into ascending order using the less-than operator. + * + * \param range the range of elements to be sorted + */ + template<typename Range> inline void sort(Range &range){ + return std::sort(boost::begin(range), boost::end(range)); + } + + /*! + * A wrapper around std::sort that takes a range instead of an iterator. + * + * The elements are sorted into ascending order using the less-than operator. + * This wrapper sorts the elements non-destructively into a new range. + * Based on the builtin python function sorted(...) + * + * \param range the range of elements to be sorted + * \return a new range with the elements sorted + */ + template<typename Range> inline Range sorted(const Range &range){ + Range srange(range); std::sort(srange); return srange; + } + + /*! + * A wrapper around std::reverse that takes a range instead of an iterator. + * + * The elements are reversed into descending order using the less-than operator. + * + * \param range the range of elements to be reversed + */ + template<typename Range> inline void reverse(Range &range){ + return std::reverse(boost::begin(range), boost::end(range)); + } + + /*! + * A wrapper around std::reverse that takes a range instead of an iterator. + * + * The elements are reversed into descending order using the less-than operator. + * This wrapper reverses the elements non-destructively into a new range. + * Based on the builtin python function reversed(...) + * + * \param range the range of elements to be reversed + * \return a new range with the elements reversed + */ + template<typename Range> inline Range reversed(const Range &range){ + Range srange(range); std::reverse(srange); return srange; + } + + /*! + * Is the value found within the elements in this range? + * + * Uses std::find to search the iterable for an element. + * + * \param range the elements to search through + * \param value the match to look for in the range + * \return true when the value is found in the range + */ + template<typename Range, typename T> inline + bool has(const Range &range, const T &value){ + return boost::end(range) != std::find(boost::begin(range), boost::end(range), value); + } + + /*! + * Count the number of appearances of a value in a range. + * + * Uses std::count to count the appearances in the range. + * + * \param range the elements to iterate through + * \param value the value to count in the range + * \return the number of appearances of the value + */ + template<typename Range, typename T> inline + size_t count(const Range &range, const T &value){ + return std::count(boost::begin(range), boost::end(range), value); + } + + /*! + * Are the ranges equal (are their elements equivalent)? + * + * Uses std::equal to search the iterable for an element. + * + * \param range1 the first range of elements + * \param range2 the second range of elements + * \return true when the elements are equivalent + */ + template<typename Range> inline + bool equal(const Range &range1, const Range &range2){ + return (boost::size(range1) == boost::size(range2)) and + std::equal(boost::begin(range1), boost::end(range1), boost::begin(range2)); + } + + /*! + * A templated clip implementation. + * \param val the value to clip between an upper and lower limit + * \param bound1 the upper or lower bound + * \param bound2 the upper or lower bound + * \return the value clipped at the bounds + */ + template<typename T> inline T clip(T val, T bound1, T bound2){ + return std::min(std::max(val, std::min(bound1, bound2)), std::max(bound1, bound2)); + } + +}//namespace std + +#endif /* INCLUDED_UHD_UTILS_ALGORITHM_HPP */ diff --git a/host/include/uhd/utils/assert.hpp b/host/include/uhd/utils/assert.hpp new file mode 100644 index 000000000..7f7b71cfb --- /dev/null +++ b/host/include/uhd/utils/assert.hpp @@ -0,0 +1,59 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_UTILS_ASSERT_HPP +#define INCLUDED_UHD_UTILS_ASSERT_HPP + +#include <uhd/config.hpp> +#include <uhd/utils/exception.hpp> +#include <stdexcept> +#include <string> + +namespace uhd{ + + //! The exception to throw when assertions fail + struct UHD_API assert_error : std::runtime_error{ + assert_error(const std::string &what); + }; + + //! Throw an assert error with throw-site information + #define UHD_ASSERT_THROW(_x) if (not (_x)) throw uhd::assert_error( \ + UHD_THROW_SITE_INFO("assertion failed: " + std::string(#_x)) \ + ); else void(0) + + /*! + * Check that an element is found in a container. + * If not, throw a meaningful assertion error. + * The "what" in the error will show what is + * being set and a list of known good values. + * + * \param range a list of possible settings + * \param value an element that may be in the list + * \param what a description of what the value is + * \throw assertion_error when elem not in list + */ + template<typename T, typename Range> void assert_has( + const Range &range, + const T &value, + const std::string &what = "unknown" + ); + +}//namespace uhd + +#include <uhd/utils/assert.ipp> + +#endif /* INCLUDED_UHD_UTILS_ASSERT_HPP */ diff --git a/host/include/uhd/utils/assert.ipp b/host/include/uhd/utils/assert.ipp new file mode 100644 index 000000000..6a8b3e417 --- /dev/null +++ b/host/include/uhd/utils/assert.ipp @@ -0,0 +1,52 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_UTILS_ASSERT_IPP +#define INCLUDED_UHD_UTILS_ASSERT_IPP + +#include <uhd/utils/algorithm.hpp> +#include <boost/format.hpp> +#include <boost/foreach.hpp> +#include <boost/lexical_cast.hpp> + +namespace uhd{ + + template<typename T, typename Range> UHD_INLINE void assert_has( + const Range &range, + const T &value, + const std::string &what + ){ + if (std::has(range, value)) return; + std::string possible_values = ""; + size_t i = 0; + BOOST_FOREACH(const T &v, range){ + if (i++ > 0) possible_values += ", "; + possible_values += boost::lexical_cast<std::string>(v); + } + throw uhd::assert_error(str(boost::format( + "assertion failed:\n" + " %s is not a valid %s.\n" + " possible values are: [%s].\n" + ) + % boost::lexical_cast<std::string>(value) + % what % possible_values + )); + } + +}//namespace uhd + +#endif /* INCLUDED_UHD_UTILS_ASSERT_IPP */ diff --git a/host/include/uhd/utils/byteswap.hpp b/host/include/uhd/utils/byteswap.hpp new file mode 100644 index 000000000..9a1871210 --- /dev/null +++ b/host/include/uhd/utils/byteswap.hpp @@ -0,0 +1,50 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_UTILS_BYTESWAP_HPP +#define INCLUDED_UHD_UTILS_BYTESWAP_HPP + +#include <uhd/config.hpp> +#include <boost/cstdint.hpp> + +/*! \file byteswap.hpp + * Provide fast byteswaping routines for 16, 32, and 64 bit integers, + * by using the system's native routines/intrinsics when available. + */ + +namespace uhd{ + + //! perform a byteswap on a 16 bit integer + boost::uint16_t byteswap(boost::uint16_t); + + //! perform a byteswap on a 32 bit integer + boost::uint32_t byteswap(boost::uint32_t); + + //! perform a byteswap on a 64 bit integer + boost::uint64_t byteswap(boost::uint64_t); + + //! network to host: short, long, or long-long + template<typename T> T ntohx(T); + + //! host to network: short, long, or long-long + template<typename T> T htonx(T); + +} //namespace uhd + +#include <uhd/utils/byteswap.ipp> + +#endif /* INCLUDED_UHD_UTILS_BYTESWAP_HPP */ diff --git a/host/include/uhd/utils/byteswap.ipp b/host/include/uhd/utils/byteswap.ipp new file mode 100644 index 000000000..a070a7cf5 --- /dev/null +++ b/host/include/uhd/utils/byteswap.ipp @@ -0,0 +1,120 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_UTILS_BYTESWAP_IPP +#define INCLUDED_UHD_UTILS_BYTESWAP_IPP + +/*********************************************************************** + * Platform-specific implementation details for byteswap below: + **********************************************************************/ +#if defined(UHD_PLATFORM_WIN32) //http://msdn.microsoft.com/en-us/library/a3140177%28VS.80%29.aspx + #include <stdlib.h> + + UHD_INLINE boost::uint16_t uhd::byteswap(boost::uint16_t x){ + return _byteswap_ushort(x); + } + + UHD_INLINE boost::uint32_t uhd::byteswap(boost::uint32_t x){ + return _byteswap_ulong(x); + } + + UHD_INLINE boost::uint64_t uhd::byteswap(boost::uint64_t x){ + return _byteswap_uint64(x); + } + +#elif defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 2 + + UHD_INLINE boost::uint16_t uhd::byteswap(boost::uint16_t x){ + return (x>>8) | (x<<8); //DNE return __builtin_bswap16(x); + } + + UHD_INLINE boost::uint32_t uhd::byteswap(boost::uint32_t x){ + return __builtin_bswap32(x); + } + + UHD_INLINE boost::uint64_t uhd::byteswap(boost::uint64_t x){ + return __builtin_bswap64(x); + } + +#elif defined(UHD_PLATFORM_MACOS) + #include <libkern/OSByteOrder.h> + + UHD_INLINE boost::uint16_t uhd::byteswap(boost::uint16_t x){ + return OSSwapInt16(x); + } + + UHD_INLINE boost::uint32_t uhd::byteswap(boost::uint32_t x){ + return OSSwapInt32(x); + } + + UHD_INLINE boost::uint64_t uhd::byteswap(boost::uint64_t x){ + return OSSwapInt64(x); + } + +#elif defined(UHD_PLATFORM_LINUX) + #include <byteswap.h> + + UHD_INLINE boost::uint16_t uhd::byteswap(boost::uint16_t x){ + return bswap_16(x); + } + + UHD_INLINE boost::uint32_t uhd::byteswap(boost::uint32_t x){ + return bswap_32(x); + } + + UHD_INLINE boost::uint64_t uhd::byteswap(boost::uint64_t x){ + return bswap_64(x); + } + +#else //http://www.koders.com/c/fidB93B34CD44F0ECF724F1A4EAE3854BA2FE692F59.aspx + + UHD_INLINE boost::uint16_t uhd::byteswap(boost::uint16_t x){ + return (x>>8) | (x<<8); + } + + UHD_INLINE boost::uint32_t uhd::byteswap(boost::uint32_t x){ + return (boost::uint32_t(uhd::byteswap(boost::uint16_t(x&0xfffful)))<<16) | (uhd::byteswap(boost::uint16_t(x>>16))); + } + + UHD_INLINE boost::uint64_t uhd::byteswap(boost::uint64_t x){ + return (boost::uint64_t(uhd::byteswap(boost::uint32_t(x&0xffffffffull)))<<32) | (uhd::byteswap(boost::uint32_t(x>>32))); + } + +#endif + +/*********************************************************************** + * Define the templated network to/from host conversions + **********************************************************************/ +#include <boost/detail/endian.hpp> + +template<typename T> UHD_INLINE T uhd::ntohx(T num){ + #ifdef BOOST_BIG_ENDIAN + return num; + #else + return uhd::byteswap(num); + #endif +} + +template<typename T> UHD_INLINE T uhd::htonx(T num){ + #ifdef BOOST_BIG_ENDIAN + return num; + #else + return uhd::byteswap(num); + #endif +} + +#endif /* INCLUDED_UHD_UTILS_BYTESWAP_IPP */ diff --git a/host/include/uhd/utils/exception.hpp b/host/include/uhd/utils/exception.hpp new file mode 100644 index 000000000..e74c19b9c --- /dev/null +++ b/host/include/uhd/utils/exception.hpp @@ -0,0 +1,45 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_UTILS_EXCEPTION_HPP +#define INCLUDED_UHD_UTILS_EXCEPTION_HPP + +#include <uhd/config.hpp> +#include <boost/current_function.hpp> +#include <stdexcept> +#include <string> + +/*! + * Create a formated string with throw-site information. + * Fills in the function name, file name, and line number. + * \param what the std::exeption message + * \return the formatted exception message + */ +#define UHD_THROW_SITE_INFO(what) std::string( \ + std::string(what) + "\n" + \ + " in " + std::string(BOOST_CURRENT_FUNCTION) + "\n" + \ + " at " + std::string(__FILE__) + ":" + BOOST_STRINGIZE(__LINE__) + "\n" \ +) + +/*! + * Throws an invalid code path exception with throw-site information. + * Use this macro in places that code execution is not supposed to go. + */ +#define UHD_THROW_INVALID_CODE_PATH() \ + throw std::runtime_error(UHD_THROW_SITE_INFO("invalid code path")) + +#endif /* INCLUDED_UHD_UTILS_EXCEPTION_HPP */ diff --git a/host/include/uhd/utils/gain_group.hpp b/host/include/uhd/utils/gain_group.hpp new file mode 100644 index 000000000..3955dfa9a --- /dev/null +++ b/host/include/uhd/utils/gain_group.hpp @@ -0,0 +1,85 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_UTILS_GAIN_GROUP_HPP +#define INCLUDED_UHD_UTILS_GAIN_GROUP_HPP + +#include <uhd/config.hpp> +#include <uhd/types/ranges.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/function.hpp> +#include <boost/utility.hpp> + +namespace uhd{ + +/*! + * A set of function to control a gain element. + */ +struct UHD_API gain_fcns_t{ + boost::function<gain_range_t(void)> get_range; + boost::function<float(void)> get_value; + boost::function<void(float)> set_value; +}; + +class UHD_API gain_group : boost::noncopyable{ +public: + typedef boost::shared_ptr<gain_group> sptr; + + /*! + * Get the overall gain range for this group. + * Overall step is defined as the minimum step size. + * \return a gain range with overall min, max, step + */ + virtual gain_range_t get_range(void) = 0; + + /*! + * Get the overall gain value for this group. + * \return a summation of all the gain values + */ + virtual float get_value(void) = 0; + + /*! + * Set the overall gain value for this group. + * The power will be distributed across individual gain elements. + * The semantics of how to do this are determined by the priority. + * \param gain the gain to set across the group + */ + virtual void set_value(float gain) = 0; + + /*! + * Register a set of gain functions into this group. + * Priority determines how power will be distributed + * with higher priorities getting the power first, + * and lower priorities getting the remainder power. + * \param gain_fcns the set of gain functions + * \param priority the priority of the gain element + */ + virtual void register_fcns( + const gain_fcns_t &gain_fcns, size_t priority = 0 + ) = 0; + + /*! + * Make a new empty gain group. + * \return a gain group object. + */ + static sptr make(void); +}; + +} //namespace uhd + +#endif /* INCLUDED_UHD_UTILS_GAIN_GROUP_HPP */ + diff --git a/host/include/uhd/utils/pimpl.hpp b/host/include/uhd/utils/pimpl.hpp new file mode 100644 index 000000000..18454f0c4 --- /dev/null +++ b/host/include/uhd/utils/pimpl.hpp @@ -0,0 +1,56 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_UTILS_PIMPL_HPP +#define INCLUDED_UHD_UTILS_PIMPL_HPP + +#include <uhd/config.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/make_shared.hpp> + +/*! \file pimpl.hpp + * "Pimpl idiom" (pointer to implementation idiom). + * The UHD_PIMPL_* macros simplify code overhead for declaring and making pimpls. + * + * Each pimpl is implemented as a shared pointer to the implementation: + * - The container class will not have to deallocate the pimpl. + * - The container class will use the pimpl as a regular pointer. + * - Usage: _impl->method(arg0, arg1) + * - Usage: _impl->member = value; + * + * \see http://en.wikipedia.org/wiki/Opaque_pointer + */ + +/*! + * Make a declaration for a pimpl in a header file. + * - Usage: UHD_PIMPL_DECL(impl) _impl; + * \param _name the name of the pimpl class + */ +#define UHD_PIMPL_DECL(_name) \ + struct _name; boost::shared_ptr<_name> + +/*! + * Make an instance of a pimpl in a source file. + * - Usage: _impl = UHD_PIMPL_MAKE(impl, ()); + * - Usage: _impl = UHD_PIMPL_MAKE(impl, (a0, a1)); + * \param _name the name of the pimpl class + * \param _args the constructor args for the pimpl + */ +#define UHD_PIMPL_MAKE(_name, _args) \ + boost::make_shared<_name> _args + +#endif /* INCLUDED_UHD_UTILS_PIMPL_HPP */ diff --git a/host/include/uhd/utils/props.hpp b/host/include/uhd/utils/props.hpp new file mode 100644 index 000000000..f376d2612 --- /dev/null +++ b/host/include/uhd/utils/props.hpp @@ -0,0 +1,77 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_UTILS_PROPS_HPP +#define INCLUDED_UHD_UTILS_PROPS_HPP + +#include <uhd/config.hpp> +#include <uhd/wax.hpp> +#include <uhd/utils/exception.hpp> +#include <boost/tuple/tuple.hpp> +#include <stdexcept> +#include <vector> +#include <string> + +namespace uhd{ + + //! The type for a vector of property names + typedef std::vector<std::string> prop_names_t; + + /*! + * A named prop struct holds a key and a name. + * Allows properties to be sub-sectioned by name. + */ + struct UHD_API named_prop_t{ + wax::obj key; + std::string name; + + /*! + * Create a new named prop from key and name. + * \param key the property key + * \param name the string name + */ + named_prop_t(const wax::obj &key, const std::string &name); + }; + + /*! + * Utility function to separate a named property into its components. + * \param key a reference to the prop object + * \param name a reference to the name object + * \return a tuple that can be used with boost::tie + */ + UHD_API boost::tuple<wax::obj, std::string> extract_named_prop( + const wax::obj &key, + const std::string &name = "" + ); + + /*! + * Throw when getting a not-implemented or write-only property. + * Throw-site information will be included with this error. + */ + #define UHD_THROW_PROP_GET_ERROR() \ + throw std::runtime_error(UHD_THROW_SITE_INFO("cannot get this property")) + + /*! + * Throw when setting a not-implemented or read-only property. + * Throw-site information will be included with this error. + */ + #define UHD_THROW_PROP_SET_ERROR() \ + throw std::runtime_error(UHD_THROW_SITE_INFO("cannot set this property")) + +} //namespace uhd + +#endif /* INCLUDED_UHD_UTILS_PROPS_HPP */ diff --git a/host/include/uhd/utils/safe_main.hpp b/host/include/uhd/utils/safe_main.hpp new file mode 100644 index 000000000..b682aa540 --- /dev/null +++ b/host/include/uhd/utils/safe_main.hpp @@ -0,0 +1,44 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_UTILS_SAFE_MAIN_HPP +#define INCLUDED_UHD_UTILS_SAFE_MAIN_HPP + +#include <uhd/config.hpp> +#include <iostream> +#include <stdexcept> + +/*! + * Defines a safe wrapper that places a catch-all around main. + * If an exception is thrown, it prints to stderr and returns. + * Usage: int UHD_SAFE_MAIN(int argc, char *argv[]){ main code here } + * \param _argc the declaration for argc + * \param _argv the declaration for argv + */ +#define UHD_SAFE_MAIN(_argc, _argv) _main(int, char*[]); \ +int main(int argc, char *argv[]){ \ + try { \ + return _main(argc, argv); \ + } catch(const std::exception &e) { \ + std::cerr << "Error: " << e.what() << std::endl; \ + } catch(...) { \ + std::cerr << "Error: unknown exception" << std::endl; \ + } \ + return ~0; \ +} int _main(_argc, _argv) + +#endif /* INCLUDED_UHD_UTILS_SAFE_MAIN_HPP */ diff --git a/host/include/uhd/utils/static.hpp b/host/include/uhd/utils/static.hpp new file mode 100644 index 000000000..c61f10884 --- /dev/null +++ b/host/include/uhd/utils/static.hpp @@ -0,0 +1,37 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_UTILS_STATIC_HPP +#define INCLUDED_UHD_UTILS_STATIC_HPP + +#include <uhd/config.hpp> + +/*! + * Defines a function that implements the "construct on first use" idiom + * \param _t the type definition for the instance + * \param _x the name of the defined function + * \return a reference to the lazy instance + */ +#define UHD_SINGLETON_FCN(_t, _x) static _t &_x(){static _t _x; return _x;} + +/*! + * Defines a static code block that will be called before main() + * \param _x the name of the defined struct (must be unique in file) + */ +#define UHD_STATIC_BLOCK(_x) static struct _x{_x();}_x;_x::_x() + +#endif /* INCLUDED_UHD_UTILS_STATIC_HPP */ diff --git a/host/include/uhd/utils/thread_priority.hpp b/host/include/uhd/utils/thread_priority.hpp new file mode 100644 index 000000000..988fc3012 --- /dev/null +++ b/host/include/uhd/utils/thread_priority.hpp @@ -0,0 +1,58 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_UTILS_THREAD_PRIORITY_HPP +#define INCLUDED_UHD_UTILS_THREAD_PRIORITY_HPP + +#include <uhd/config.hpp> + +namespace uhd{ + + static const float default_thread_priority = float(0.5); + + /*! + * Set the scheduling priority on the current thread. + * + * A new thread or calling process should make this call + * with the defailts this to enable realtime scheduling. + * + * A priority of zero corresponds to normal priority. + * Positive priority values are higher than normal. + * Negative priority values are lower than normal. + * + * \param priority a value between -1 and 1 + * \param realtime true to use realtime mode + * \throw exception on set priority failure + */ + UHD_API void set_thread_priority( + float priority = default_thread_priority, + bool realtime = true + ); + + /*! + * Set the scheduling priority on the current thread. + * Same as set_thread_priority but does not throw on failure. + * \return true on success, false on failure + */ + UHD_API bool set_thread_priority_safe( + float priority = default_thread_priority, + bool realtime = true + ); + +} //namespace uhd + +#endif /* INCLUDED_UHD_UTILS_THREAD_PRIORITY_HPP */ diff --git a/host/include/uhd/utils/warning.hpp b/host/include/uhd/utils/warning.hpp new file mode 100644 index 000000000..91d8400ab --- /dev/null +++ b/host/include/uhd/utils/warning.hpp @@ -0,0 +1,34 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_UTILS_WARNING_HPP +#define INCLUDED_UHD_UTILS_WARNING_HPP + +#include <uhd/config.hpp> +#include <string> + +namespace uhd{ + + /*! + * Print a formatted warning string to stderr. + * \param msg the multiline warning message + */ + UHD_API void print_warning(const std::string &msg); + +} //namespace uhd + +#endif /* INCLUDED_UHD_UTILS_WARNING_HPP */ diff --git a/host/include/uhd/version.hpp b/host/include/uhd/version.hpp new file mode 100644 index 000000000..19d672e65 --- /dev/null +++ b/host/include/uhd/version.hpp @@ -0,0 +1,28 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_VERSION_HPP +#define INCLUDED_UHD_VERSION_HPP + +#include <uhd/config.hpp> +#include <string> + +namespace uhd{ + UHD_API std::string get_version_string(void); +} //namespace uhd + +#endif /* INCLUDED_UHD_VERSION_HPP */ diff --git a/host/include/uhd/wax.hpp b/host/include/uhd/wax.hpp new file mode 100644 index 000000000..14e6734a5 --- /dev/null +++ b/host/include/uhd/wax.hpp @@ -0,0 +1,167 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_WAX_HPP +#define INCLUDED_WAX_HPP + +#include <uhd/config.hpp> +#include <boost/any.hpp> + +/*! + * WAX - it's a metaphor! + * + * The WAX framework allows an object to have generic/anyobj properties. + * These properties can be addressed through generic/anyobj identifiers. + * + * The WAX object itself is an anytype container much like boost::any. + * To retrieve the value of the appropriate type, use my_obj.as<type>(). + * + * Proprties may be referenced though the [] overloaded operator. + * The [] operator returns a special proxy that allows for assigment. + * Also, the [] operators may be chained as in the folowing examples: + * my_obj[prop1][prop2][prop3] = value; + * value = my_obj[prop1][prop2][prop3].as<type>(); + * + * Property nesting occurs when a WAX object gets another object's link. + * This special link is obtained through a call to my_obj.get_link(). + * + * Note: Do not put a class derived from wax::obj into an stl container. + * MSVC will compile the code, but the binaries will crash at runtime. + * Rather, use pointers or smart pointers to instances of the derived class. + */ + +namespace wax{ + + /*! + * The wax::bad cast will be thrown when + * cast is called with the wrong typeid. + */ + typedef boost::bad_any_cast bad_cast; + + /*! + * WAX object base class: + * + * A wax obj has two major purposes: + * 1) to act as a polymorphic container, just like boost any + * 2) to provide a nested set/get properties interface + * + * Internally, the polymorphic container is handled by a boost any. + * For properties, a subclass should override the set and get methods. + * For property nesting, wax obj subclasses return special links + * to other wax obj subclasses, and the api handles the magic. + */ + class UHD_API obj{ + public: + + /*! + * Default constructor: + * The contents will be empty. + */ + obj(void); + + /*! + * Copy constructor: + * The contents will be cloned. + * \param o another wax::obj + */ + obj(const obj &o); + + /*! + * Templated any type constructor: + * The contents can be anything. + * Uses the boost::any to handle the magic. + * \param o an object of any type + */ + template<class T> obj(const T &o){ + _contents = o; + } + + /*! + * Destructor. + */ + virtual ~obj(void); + + /*! + * The chaining operator: + * This operator allows access objs with properties. + * A call to the [] operator will return a new proxy obj. + * The proxy object is an obj with special proxy contents. + * Assignment and casting can be used on this special object + * to access the property referenced by the obj key. + * \param key a key to identify a property within this obj + * \return a special wax obj that proxies the obj and key + */ + obj operator[](const obj &key); + + /*! + * The assignment operator: + * This operator allows for assignment of new contents. + * In the special case where this obj contains a proxy, + * the value will be set to the proxy's property reference. + * \param val the new value to assign to the wax obj + * \return a reference to this obj (*this) + */ + obj & operator=(const obj &val); + + /*! + * Get a link in the chain: + * When a wax obj returns another wax obj as part of a get call, + * the return value should be set to the result of this method. + * Doing so will ensure chain-ability of the returned object. + * \return an obj containing a valid link to a wax obj + */ + obj get_link(void) const; + + /*! + * Get the type of the contents of this obj. + * \return a reference to the type_info + */ + const std::type_info & type(void) const; + + /*! + * Cast this obj into the desired type. + * Usage: myobj.as<type>() + * + * \return an object of the desired type + * \throw wax::bad_cast when the cast fails + */ + template<class T> T as(void) const{ + return boost::any_cast<T>(resolve()); + } + + private: + //private interface (override in subclasses) + virtual void get(const obj &, obj &); + virtual void set(const obj &, const obj &); + + /*! + * Resolve the contents of this obj. + * In the case where this obj is a proxy, + * the referenced property will be resolved. + * Otherwise, just get the private contents. + * \return a boost any type with contents + */ + boost::any resolve(void) const; + + //private contents of this obj + boost::any _contents; + + }; + +} //namespace wax + +#endif /* INCLUDED_WAX_HPP */ |