diff options
author | root <root@usrp1-e.(none)> | 2010-03-23 13:35:36 +0000 |
---|---|---|
committer | root <root@usrp1-e.(none)> | 2010-03-23 13:35:36 +0000 |
commit | c329da8f953c3981e23791c688f350b27541554a (patch) | |
tree | 3447dd657bf7221e3b4b1a9147ce1bd2ffa430b9 /host/include | |
parent | f6ec1e45117f5794facd1cd8e11cbfacabdeb166 (diff) | |
parent | 09a21dd6d4bc5b7f032e07cfabcba9f55d25b0f6 (diff) | |
download | uhd-c329da8f953c3981e23791c688f350b27541554a.tar.gz uhd-c329da8f953c3981e23791c688f350b27541554a.tar.bz2 uhd-c329da8f953c3981e23791c688f350b27541554a.zip |
Merge branch 'u1e_uhd' of git@ettus.sourcerepo.com:ettus/uhd into u1e_uhd
Diffstat (limited to 'host/include')
29 files changed, 972 insertions, 415 deletions
diff --git a/host/include/CMakeLists.txt b/host/include/CMakeLists.txt index 34b705cab..3f7ca2cb7 100644 --- a/host/include/CMakeLists.txt +++ b/host/include/CMakeLists.txt @@ -17,8 +17,3 @@ ADD_SUBDIRECTORY(uhd) - -INSTALL(FILES - uhd.hpp - DESTINATION ${HEADER_DIR} -) diff --git a/host/include/uhd.hpp b/host/include/uhd.hpp deleted file mode 100644 index ee8c13dfe..000000000 --- a/host/include/uhd.hpp +++ /dev/null @@ -1,24 +0,0 @@ -// -// Copyright 2010 Ettus Research LLC -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -// - -#ifndef INCLUDED_UHD_HPP -#define INCLUDED_UHD_HPP - -//include convenience headers -#include <uhd/device.hpp> - -#endif /* INCLUDED_UHD_HPP */ diff --git a/host/include/uhd/CMakeLists.txt b/host/include/uhd/CMakeLists.txt index 006c54f22..3d00462cf 100644 --- a/host/include/uhd/CMakeLists.txt +++ b/host/include/uhd/CMakeLists.txt @@ -20,13 +20,16 @@ ADD_SUBDIRECTORY(transport) ADD_SUBDIRECTORY(usrp) INSTALL(FILES + config.hpp device.hpp device_addr.hpp dict.hpp gain_handler.hpp + metadata.hpp props.hpp - shared_iovec.hpp + simple_device.hpp time_spec.hpp + types.hpp utils.hpp wax.hpp DESTINATION ${HEADER_DIR}/uhd diff --git a/host/include/uhd/config.hpp b/host/include/uhd/config.hpp new file mode 100644 index 000000000..10f9c093f --- /dev/null +++ b/host/include/uhd/config.hpp @@ -0,0 +1,76 @@ +//
+// 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
+#endif
+
+// http://gcc.gnu.org/wiki/Visibility
+// Generic helper definitions for shared library support
+#if defined _WIN32 || defined __CYGWIN__
+ #define UHD_HELPER_DLL_IMPORT __declspec(dllimport)
+ #define UHD_HELPER_DLL_EXPORT __declspec(dllexport)
+ #define UHD_HELPER_DLL_LOCAL
+#else
+ #if __GNUC__ >= 4
+ #define UHD_HELPER_DLL_IMPORT __attribute__ ((visibility("default")))
+ #define UHD_HELPER_DLL_EXPORT __attribute__ ((visibility("default")))
+ #define UHD_HELPER_DLL_LOCAL __attribute__ ((visibility("hidden")))
+ #else
+ #define UHD_HELPER_DLL_IMPORT
+ #define UHD_HELPER_DLL_EXPORT
+ #define UHD_HELPER_DLL_LOCAL
+ #endif
+#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
+
+#endif /* INCLUDED_UHD_CONFIG_HPP */
diff --git a/host/include/uhd/device.hpp b/host/include/uhd/device.hpp index dfbfbd7c0..13b40febe 100644 --- a/host/include/uhd/device.hpp +++ b/host/include/uhd/device.hpp @@ -18,15 +18,15 @@ #ifndef INCLUDED_UHD_DEVICE_HPP #define INCLUDED_UHD_DEVICE_HPP +#include <uhd/config.hpp> #include <uhd/device_addr.hpp> #include <uhd/props.hpp> +#include <uhd/metadata.hpp> #include <uhd/wax.hpp> #include <boost/utility.hpp> #include <boost/shared_ptr.hpp> #include <boost/function.hpp> #include <boost/asio/buffer.hpp> -#include <uhd/shared_iovec.hpp> -#include <vector> namespace uhd{ @@ -34,14 +34,23 @@ namespace uhd{ * The usrp device interface represents the usrp hardware. * The api allows for discovery, configuration, and streaming. */ -class device : boost::noncopyable, public wax::obj{ +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 &)> discover_t; + typedef boost::function<sptr(const device_addr_t &)> make_t; - //structors - device(void); - virtual ~device(void); + /*! + * Register a device into the discovery and factory system. + * + * \param discover a function that discovers devices + * \param make a factory function that makes a device + */ + static void register_device( + const discover_t &discover, + const make_t &make + ); /*! * \brief Discover usrp devices attached to the host. @@ -68,13 +77,60 @@ public: static sptr make(const device_addr_t &hint, size_t which = 0); /*! - * Get the device address for this board. + * Send a buffer containing IF data with its metadata. + * + * Send handles fragmentation as follows: + * If the buffer has more samples than the maximum supported, + * the send method will send the maximum number of samples + * as supported by the transport and return the number sent. + * It is up to the caller to call send again on the un-sent + * portions of the buffer, until the buffer is exhausted. + * + * This is a blocking call and will not return until the number + * of samples returned have been read out of the buffer. + * + * \param buff a buffer pointing to some read-only memory + * \param metadata data describing the buffer's contents + * \param the type of data loaded in the buffer (32fc, 16sc) + * \return the number of samples sent */ - device_addr_t get_device_addr(void); + virtual size_t send( + const boost::asio::const_buffer &buff, + const tx_metadata_t &metadata, + const std::string &type = "32fc" + ) = 0; - //the io interface - virtual void send_raw(const std::vector<boost::asio::const_buffer> &) = 0; - virtual uhd::shared_iovec recv_raw(void) = 0; + /*! + * Receive a buffer containing IF data and its 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. + * + * This is a blocking call and will not return until the number + * of samples returned have been written into the buffer. + * However, a call to receive may timeout and return zero samples. + * The timeout duration is decided by the underlying transport layer. + * The caller should assume that the call to receive will not return + * immediately when no packets are available to the transport layer, + * and that the timeout duration is reasonably tuned for performance. + * + * \param buff the buffer to fill with IF data + * \param metadata data to fill describing the buffer + * \param the type of data to fill into the buffer (32fc, 16sc) + * \return the number of samples received + */ + virtual size_t recv( + const boost::asio::mutable_buffer &buff, + rx_metadata_t &metadata, + const std::string &type = "32fc" + ) = 0; }; } //namespace uhd diff --git a/host/include/uhd/device_addr.hpp b/host/include/uhd/device_addr.hpp index 8ea580321..7673faff0 100644 --- a/host/include/uhd/device_addr.hpp +++ b/host/include/uhd/device_addr.hpp @@ -18,11 +18,11 @@ #ifndef INCLUDED_UHD_DEVICE_ADDR_HPP #define INCLUDED_UHD_DEVICE_ADDR_HPP +#include <uhd/config.hpp> #include <uhd/dict.hpp> +#include <boost/cstdint.hpp> #include <string> #include <iostream> -#include <netinet/ether.h> -#include <stdint.h> #include <vector> namespace uhd{ @@ -31,8 +31,8 @@ namespace uhd{ * Wrapper for an ethernet mac address. * Provides conversion between string and binary formats. */ - struct mac_addr_t{ - struct ether_addr mac_addr; + struct UHD_API mac_addr_t{ + boost::uint8_t mac_addr[6]; mac_addr_t(const std::string &mac_addr_str = "00:00:00:00:00:00"); std::string to_string(void) const; }; @@ -56,12 +56,14 @@ namespace uhd{ * \param device_addr a device address instance * \return the string representation */ - std::string device_addr_to_string(const device_addr_t &device_addr); + namespace device_addr{ + UHD_API std::string to_string(const device_addr_t &device_addr); + } } //namespace uhd //ability to use types with stream operators -std::ostream& operator<<(std::ostream &, const uhd::device_addr_t &); -std::ostream& operator<<(std::ostream &, const uhd::mac_addr_t &); +UHD_API std::ostream& operator<<(std::ostream &, const uhd::device_addr_t &); +UHD_API std::ostream& operator<<(std::ostream &, const uhd::mac_addr_t &); #endif /* INCLUDED_UHD_DEVICE_ADDR_HPP */ diff --git a/host/include/uhd/dict.hpp b/host/include/uhd/dict.hpp index 1ed28551a..f08493952 100644 --- a/host/include/uhd/dict.hpp +++ b/host/include/uhd/dict.hpp @@ -18,7 +18,7 @@ #ifndef INCLUDED_UHD_DICT_HPP #define INCLUDED_UHD_DICT_HPP -#include <map> +#include <list> #include <vector> #include <stdexcept> #include <boost/foreach.hpp> @@ -27,11 +27,9 @@ namespace uhd{ /*! * A templated dictionary class with a python-like interface. - * Its wraps around a std::map internally. */ template <class Key, class Val> class dict{ public: - typedef std::map<Key, Val> map_t; typedef std::pair<Key, Val> pair_t; /*! @@ -42,11 +40,16 @@ namespace uhd{ } /*! - * Create a dictionary from a map. - * \param map a map with key value pairs + * Input iterator constructor: + * Makes boost::assign::map_list_of work. + * \param first the begin iterator + * \param last the end iterator */ - dict(const map_t &map){ - _map = map; + template <class InputIterator> + dict(InputIterator first, InputIterator last){ + for(InputIterator it = first; it != last; it++){ + _map.push_back(*it); + } } /*! @@ -57,12 +60,21 @@ namespace uhd{ } /*! + * Get the number of elements in this dict. + * \param 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 */ std::vector<Key> get_keys(void) const{ std::vector<Key> keys; - BOOST_FOREACH(pair_t p, _map){ + BOOST_FOREACH(const pair_t &p, _map){ keys.push_back(p.first); } return keys; @@ -70,11 +82,12 @@ namespace uhd{ /*! * Get a list of the values in this dict. + * Value order depends on insertion precedence. * \return vector of values */ std::vector<Val> get_vals(void) const{ std::vector<Val> vals; - BOOST_FOREACH(pair_t p, _map){ + BOOST_FOREACH(const pair_t &p, _map){ vals.push_back(p.second); } return vals; @@ -86,7 +99,7 @@ namespace uhd{ * \return true if found */ bool has_key(const Key &key) const{ - BOOST_FOREACH(pair_t p, _map){ + BOOST_FOREACH(const pair_t &p, _map){ if (p.first == key) return true; } return false; @@ -100,8 +113,8 @@ namespace uhd{ * \throw an exception when not found */ const Val &operator[](const Key &key) const{ - if (has_key(key)){ - return _map.find(key)->second; + BOOST_FOREACH(const pair_t &p, _map){ + if (p.first == key) return p.second; } throw std::invalid_argument("key not found in dict"); } @@ -113,7 +126,11 @@ namespace uhd{ * \return a reference to the value */ Val &operator[](const Key &key){ - return _map[key]; + BOOST_FOREACH(pair_t &p, _map){ + if (p.first == key) return p.second; + } + _map.push_back(pair_t(key, Val())); + return _map.back().second; } /*! @@ -122,17 +139,14 @@ namespace uhd{ * \return the value of the item * \throw an exception when not found */ - Val pop_key(const Key &key){ - if (has_key(key)){ - Val val = _map.find(key)->second; - _map.erase(key); - return val; - } - throw std::invalid_argument("key not found in dict"); + Val pop(const Key &key){ + Val val = (*this)[key]; + _map.remove(pair_t(key, val)); + return val; } private: - map_t _map; //private container + std::list<pair_t> _map; //private container }; } //namespace uhd diff --git a/host/include/uhd/gain_handler.hpp b/host/include/uhd/gain_handler.hpp index 06800315a..65d6cecf9 100644 --- a/host/include/uhd/gain_handler.hpp +++ b/host/include/uhd/gain_handler.hpp @@ -15,43 +15,50 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include <boost/shared_ptr.hpp> -#include <uhd/wax.hpp> -#include <uhd/props.hpp> -#include <boost/function.hpp> -#include <boost/bind.hpp> - #ifndef INCLUDED_UHD_GAIN_HANDLER_HPP #define INCLUDED_UHD_GAIN_HANDLER_HPP +#include <uhd/config.hpp> +#include <uhd/wax.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/function.hpp> + namespace uhd{ -class gain_handler{ +class UHD_API gain_handler{ public: typedef boost::shared_ptr<gain_handler> sptr; + typedef boost::function<bool(const wax::obj &, const wax::obj &)> is_equal_t; - template <class T> gain_handler( - wax::obj *wax_obj_ptr, const T &gain_prop, - const T &gain_min_prop, const T &gain_max_prop, - const T &gain_step_prop, const T &gain_names_prop - ){ - _wax_obj_ptr = wax_obj_ptr; - _gain_prop = gain_prop; - _gain_min_prop = gain_min_prop; - _gain_max_prop = gain_max_prop; - _gain_step_prop = gain_step_prop; - _gain_names_prop = gain_names_prop; - _is_equal = boost::bind(&gain_handler::is_equal<T>, _1, _2); - } + /*! + * A set of properties for dealing with gains. + */ + struct UHD_API props_t{ + wax::obj value, range, names; + props_t(void); //default constructor + }; - ~gain_handler(void); + /*! + * Make a new gain handler. + * The construction arguments are agnostic to the property type. + * It is up to the caller to provide an "is_equal" function that + * can tell weather two properties (in a wax obj) are equal. + * \param link a link to the wax obj with properties + * \param props a struct of properties keys + * \param is_equal the function that tests for equal properties + */ + static sptr make( + const wax::obj &link, + const props_t &props, + is_equal_t is_equal + ); /*! * Intercept gets for overall gain, min, max, step. * Ensures that the gain name is valid. * \return true for handled, false to pass on */ - bool intercept_get(const wax::obj &key, wax::obj &val); + virtual bool intercept_get(const wax::obj &key, wax::obj &val) = 0; /*! * Intercept sets for overall gain. @@ -59,39 +66,21 @@ public: * Ensures that the new gain is within range. * \return true for handled, false to pass on */ - bool intercept_set(const wax::obj &key, const wax::obj &val); - -private: - - wax::obj *_wax_obj_ptr; - wax::obj _gain_prop; - wax::obj _gain_min_prop; - wax::obj _gain_max_prop; - wax::obj _gain_step_prop; - wax::obj _gain_names_prop; + virtual bool intercept_set(const wax::obj &key, const wax::obj &val) = 0; /*! - * Verify that the key is valid: - * If its a named prop for gain, ensure that name is valid. - * If the name if not valid, throw a std::invalid_argument. - * The name can only be valid if its in the list of gain names. - */ - void _check_key(const wax::obj &key); - - /* - * Private interface to test if two wax types are equal: + * Function template to test if two wax types are equal: * The constructor will bind an instance of this for a specific type. * This bound equals functions allows the intercept methods to be non-templated. */ template <class T> static bool is_equal(const wax::obj &a, const wax::obj &b){ try{ - return wax::cast<T>(a) == wax::cast<T>(b); + return a.as<T>() == b.as<T>(); } catch(const wax::bad_cast &){ return false; } } - boost::function<bool(const wax::obj &, const wax::obj &)> _is_equal; }; diff --git a/host/include/uhd/metadata.hpp b/host/include/uhd/metadata.hpp new file mode 100644 index 000000000..6d80f070d --- /dev/null +++ b/host/include/uhd/metadata.hpp @@ -0,0 +1,61 @@ +// +// 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_METADATA_HPP +#define INCLUDED_UHD_METADATA_HPP + +#include <uhd/config.hpp> +#include <uhd/time_spec.hpp> + +namespace uhd{ + +/*! + * RX metadata structure for describing sent IF data. + * Includes stream ID, time specification, and fragmentation flags. + * The receive routines will convert IF data headers into metadata. + */ +struct UHD_API rx_metadata_t{ + boost::uint32_t stream_id; + time_spec_t time_spec; + bool has_stream_id; + bool has_time_spec; + bool is_fragment; + + //default constructor + rx_metadata_t(void); +}; + +/*! + * TX metadata structure for describing received IF data. + * Includes stream ID, time specification, and burst flags. + * The send routines will convert the metadata to IF data headers. + */ +struct UHD_API tx_metadata_t{ + boost::uint32_t stream_id; + time_spec_t time_spec; + bool has_stream_id; + bool has_time_spec; + bool start_of_burst; + bool end_of_burst; + + //default constructor + tx_metadata_t(void); +}; + +} //namespace uhd + +#endif /* INCLUDED_UHD_METADATA_HPP */ diff --git a/host/include/uhd/props.hpp b/host/include/uhd/props.hpp index 2b6daf6c5..41e0eff63 100644 --- a/host/include/uhd/props.hpp +++ b/host/include/uhd/props.hpp @@ -15,30 +15,16 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include <boost/tuple/tuple.hpp> -#include <uhd/time_spec.hpp> -#include <uhd/wax.hpp> -#include <complex> -#include <vector> - #ifndef INCLUDED_UHD_PROPS_HPP #define INCLUDED_UHD_PROPS_HPP -namespace uhd{ - - //common typedefs for board properties - typedef float gain_t; - typedef double freq_t; - - //scalar types (have not used yet, dont uncomment until needed) - //typedef int int_scalar_t; - //typedef float real_scalar_t; - //typedef std::complex<real_scalar_t> complex_scalar_t; +#include <uhd/config.hpp> +#include <uhd/wax.hpp> +#include <boost/tuple/tuple.hpp> +#include <vector> +#include <string> - //vector types (have not used yet, dont uncomment until needed) - //typedef std::vector<int_scalar_t> int_vec_t; - //typedef std::vector<real_scalar_t> real_vec_t; - //typedef std::vector<complex_scalar_t> complex_vec_t; +namespace uhd{ //typedef for handling named properties typedef std::vector<std::string> prop_names_t; @@ -49,9 +35,10 @@ namespace uhd{ * \param key a reference to the prop object * \param name a reference to the name object */ - inline named_prop_t extract_named_prop(const wax::obj &key, const std::string &name = ""){ + inline UHD_API named_prop_t //must be exported as part of the api to work (TODO move guts to cpp file) + extract_named_prop(const wax::obj &key, const std::string &name = ""){ if (key.type() == typeid(named_prop_t)){ - return wax::cast<named_prop_t>(key); + return key.as<named_prop_t>(); } return named_prop_t(key, name); } @@ -65,7 +52,9 @@ namespace uhd{ enum device_prop_t{ DEVICE_PROP_NAME, //ro, std::string DEVICE_PROP_MBOARD, //ro, wax::obj - DEVICE_PROP_MBOARD_NAMES //ro, prop_names_t + DEVICE_PROP_MBOARD_NAMES, //ro, prop_names_t + DEVICE_PROP_MAX_RX_SAMPLES, //ro, size_t + DEVICE_PROP_MAX_TX_SAMPLES //ro, size_t }; /*! @@ -77,7 +66,6 @@ namespace uhd{ enum mboard_prop_t{ MBOARD_PROP_NAME, //ro, std::string MBOARD_PROP_OTHERS, //ro, prop_names_t - MBOARD_PROP_MTU, //ro, size_t MBOARD_PROP_CLOCK_RATE, //ro, freq_t MBOARD_PROP_RX_DSP, //ro, wax::obj MBOARD_PROP_RX_DSP_NAMES, //ro, prop_names_t @@ -87,10 +75,8 @@ namespace uhd{ MBOARD_PROP_RX_DBOARD_NAMES, //ro, prop_names_t MBOARD_PROP_TX_DBOARD, //ro, wax::obj MBOARD_PROP_TX_DBOARD_NAMES, //ro, prop_names_t - MBOARD_PROP_PPS_SOURCE, //rw, std::string (sma, mimo) + MBOARD_PROP_CLOCK_CONFIG, //rw, clock_config_t MBOARD_PROP_PPS_SOURCE_NAMES, //ro, prop_names_t - MBOARD_PROP_PPS_POLARITY, //rw, std::string (pos, neg) - MBOARD_PROP_REF_SOURCE, //rw, std::string (int, sma, mimo) MBOARD_PROP_REF_SOURCE_NAMES, //ro, prop_names_t MBOARD_PROP_TIME_NOW, //wo, time_spec_t MBOARD_PROP_TIME_NEXT_PPS //wo, time_spec_t @@ -116,24 +102,23 @@ namespace uhd{ DBOARD_PROP_NAME, //ro, std::string DBOARD_PROP_SUBDEV, //ro, wax::obj DBOARD_PROP_SUBDEV_NAMES, //ro, prop_names_t - DBOARD_PROP_CODEC //ro, wax::obj - }; + DBOARD_PROP_USED_SUBDEVS //ro, prop_names_t + //DBOARD_PROP_CODEC //ro, wax::obj //----> not sure, dont have to deal with yet + }; - /*! + /*! ------ not dealing with yet, commented out ------------ * 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{ + /*enum codec_prop_t{ CODEC_PROP_NAME, //ro, std::string CODEC_PROP_OTHERS, //ro, prop_names_t CODEC_PROP_GAIN, //rw, gain_t - CODEC_PROP_GAIN_MAX, //ro, gain_t - CODEC_PROP_GAIN_MIN, //ro, gain_t - CODEC_PROP_GAIN_STEP, //ro, gain_t + CODEC_PROP_GAIN_RANGE, //ro, gain_range_t CODEC_PROP_GAIN_NAMES, //ro, prop_names_t - CODEC_PROP_CLOCK_RATE //ro, freq_t - }; + //CODEC_PROP_CLOCK_RATE //ro, freq_t //----> not sure we care to know + };*/ /*! * Possible device subdev properties @@ -142,22 +127,19 @@ namespace uhd{ SUBDEV_PROP_NAME, //ro, std::string SUBDEV_PROP_OTHERS, //ro, prop_names_t SUBDEV_PROP_GAIN, //rw, gain_t - SUBDEV_PROP_GAIN_MAX, //ro, gain_t - SUBDEV_PROP_GAIN_MIN, //ro, gain_t - SUBDEV_PROP_GAIN_STEP, //ro, gain_t + SUBDEV_PROP_GAIN_RANGE, //ro, gain_range_t SUBDEV_PROP_GAIN_NAMES, //ro, prop_names_t SUBDEV_PROP_FREQ, //rw, freq_t - SUBDEV_PROP_FREQ_MAX, //ro, freq_t - SUBDEV_PROP_FREQ_MIN, //ro, freq_t + SUBDEV_PROP_FREQ_RANGE, //ro, freq_range_t SUBDEV_PROP_ANTENNA, //rw, std::string SUBDEV_PROP_ANTENNA_NAMES, //ro, prop_names_t SUBDEV_PROP_ENABLED, //rw, bool SUBDEV_PROP_QUADRATURE, //ro, bool SUBDEV_PROP_IQ_SWAPPED, //ro, bool SUBDEV_PROP_SPECTRUM_INVERTED, //ro, bool - SUBDEV_PROP_IS_TX, //ro, bool - SUBDEV_PROP_RSSI, //ro, gain_t - SUBDEV_PROP_BANDWIDTH //rw, freq_t + SUBDEV_PROP_LO_INTERFERES //ro, bool + //SUBDEV_PROP_RSSI, //ro, gain_t //----> not on all boards, use named prop + //SUBDEV_PROP_BANDWIDTH //rw, freq_t //----> not on all boards, use named prop }; } //namespace uhd diff --git a/host/include/uhd/shared_iovec.hpp b/host/include/uhd/shared_iovec.hpp deleted file mode 100644 index a120e55d5..000000000 --- a/host/include/uhd/shared_iovec.hpp +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright 2010 Ettus Research LLC -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -// - -#ifndef INCLUDED_UHD_SHARED_IOVEC_HPP -#define INCLUDED_UHD_SHARED_IOVEC_HPP - -#include <boost/shared_array.hpp> -#include <stdint.h> - -namespace uhd{ - -/*! - * A shared iovec contains a shared array and its length. - * Creating a new shared iovec allocates new memory. - * This memory is freed when all copies are destroyed. - */ -class shared_iovec{ -public: - /*! - * Create a shared iovec and allocate memory. - * \param len the length in bytes - */ - shared_iovec(size_t len=0); - - /*! - * Destroy a shared iovec. - * Will not free the memory unless this is the last copy. - */ - ~shared_iovec(void); - - void *base; - size_t len; - -private: - boost::shared_array<uint8_t> _shared_array; -}; - -} //namespace uhd - -#endif /* INCLUDED_UHD_SHARED_IOVEC_HPP */ diff --git a/host/include/uhd/simple_device.hpp b/host/include/uhd/simple_device.hpp new file mode 100644 index 000000000..ad25eccdc --- /dev/null +++ b/host/include/uhd/simple_device.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_SIMPLE_DEVICE_HPP +#define INCLUDED_UHD_SIMPLE_DEVICE_HPP + +#include <uhd/config.hpp> +#include <uhd/device.hpp> +#include <uhd/types.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/utility.hpp> +#include <vector> + +namespace uhd{ + +/*! + * The simple UHD device class: + * A simple device 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_device : boost::noncopyable{ +public: + typedef boost::shared_ptr<simple_device> sptr; + static sptr make(const std::string &args); + + virtual device::sptr get_device(void) = 0; + + virtual std::string get_name(void) = 0; + + /******************************************************************* + * Streaming + ******************************************************************/ + virtual void set_streaming(bool enb) = 0; + virtual bool get_streaming(void) = 0; + + /******************************************************************* + * RX methods + ******************************************************************/ + virtual void set_rx_rate(double rate) = 0; + virtual double get_rx_rate(void) = 0; + virtual std::vector<double> get_rx_rates(void) = 0; + + virtual tune_result_t set_rx_freq(double freq) = 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; + + /******************************************************************* + * TX methods + ******************************************************************/ + virtual void set_tx_rate(double rate) = 0; + virtual double get_tx_rate(void) = 0; + virtual std::vector<double> get_tx_rates(void) = 0; + + virtual tune_result_t set_tx_freq(double freq) = 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; +}; + +} //namespace uhd + +#endif /* INCLUDED_UHD_SIMPLE_DEVICE_HPP */ diff --git a/host/include/uhd/time_spec.hpp b/host/include/uhd/time_spec.hpp index e5657e555..c1e7cf3a1 100644 --- a/host/include/uhd/time_spec.hpp +++ b/host/include/uhd/time_spec.hpp @@ -15,11 +15,13 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include <stdint.h> - #ifndef INCLUDED_UHD_TIME_SPEC_HPP #define INCLUDED_UHD_TIME_SPEC_HPP +#include <uhd/config.hpp> +#include <boost/cstdint.hpp> +#include <boost/date_time/posix_time/posix_time.hpp> + namespace uhd{ /*! @@ -28,28 +30,30 @@ namespace uhd{ * The time_spec_t can be used when setting the time on devices * and for controlling the start of streaming for applicable dsps. */ - struct time_spec_t{ - uint32_t secs; - uint32_t ticks; + struct UHD_API time_spec_t{ + boost::uint32_t secs; + boost::uint32_t ticks; /*! * Create a time_spec_t that holds a wildcard time. * This will have implementation-specific meaning. */ - time_spec_t(void){ - secs = ~0; - ticks = ~0; - } + time_spec_t(void); /*! * Create a time_spec_t from seconds and ticks. * \param new_secs the new seconds * \param new_ticks the new ticks (default = 0) */ - time_spec_t(uint32_t new_secs, uint32_t new_ticks = 0){ - secs = new_secs; - ticks = new_ticks; - } + time_spec_t(boost::uint32_t new_secs, boost::uint32_t new_ticks = 0); + + /*! + * Create a time_spec_t from boost posix time. + * \param time fine-grained boost posix time + * \param tick_rate the rate of ticks per second + */ + time_spec_t(boost::posix_time::ptime time, double tick_rate); + }; } //namespace uhd diff --git a/host/include/uhd/transport/CMakeLists.txt b/host/include/uhd/transport/CMakeLists.txt index b786eb945..7f5db2128 100644 --- a/host/include/uhd/transport/CMakeLists.txt +++ b/host/include/uhd/transport/CMakeLists.txt @@ -17,6 +17,9 @@ INSTALL(FILES - udp.hpp + smart_buffer.hpp + udp_simple.hpp + udp_zero_copy.hpp + vrt.hpp DESTINATION ${HEADER_DIR}/uhd/transport ) diff --git a/host/include/uhd/transport/smart_buffer.hpp b/host/include/uhd/transport/smart_buffer.hpp new file mode 100644 index 000000000..9e1032feb --- /dev/null +++ b/host/include/uhd/transport/smart_buffer.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_TRANSPORT_SMART_BUFFER_HPP +#define INCLUDED_UHD_TRANSPORT_SMART_BUFFER_HPP + +#include <boost/asio.hpp> +#include <boost/utility.hpp> +#include <boost/shared_ptr.hpp> + +namespace uhd{ namespace transport{ + +/*! + * A buffer that knows how to free itself: + * + * This is just the smart buffer interface. + * A transport implementation will have its own + * internal (custom) smart buffer implementation. + * + * A smart buffer contains a boost asio const buffer. + * On destruction, the buffer contents will be freed. + */ +class smart_buffer : boost::noncopyable{ +public: + typedef boost::shared_ptr<smart_buffer> sptr; + virtual const boost::asio::const_buffer &get(void) const = 0; +}; + +}} //namespace + +#endif /* INCLUDED_UHD_TRANSPORT_SMART_BUFFER_HPP */ diff --git a/host/include/uhd/transport/udp.hpp b/host/include/uhd/transport/udp.hpp deleted file mode 100644 index 6db6bd377..000000000 --- a/host/include/uhd/transport/udp.hpp +++ /dev/null @@ -1,75 +0,0 @@ -// -// Copyright 2010 Ettus Research LLC -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -// - -#include <boost/asio.hpp> -#include <boost/utility.hpp> -#include <boost/shared_ptr.hpp> -#include <uhd/shared_iovec.hpp> - -#ifndef INCLUDED_UHD_TRANSPORT_UDP_HPP -#define INCLUDED_UHD_TRANSPORT_UDP_HPP - -namespace uhd{ namespace transport{ - -class udp : boost::noncopyable{ -public: - typedef boost::shared_ptr<udp> sptr; - - /*! - * Constructor. - * 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 bcast if true, enable the broadcast option on the socket - */ - udp(const std::string &addr, const std::string &port, bool bcast = false); - - /*! - * Destructor - */ - ~udp(void); - - /*! - * Send a vector of buffer (like send_msg). - * \param buffs a vector of asio buffers - */ - void send(const std::vector<boost::asio::const_buffer> &buffs); - - /*! - * Send a single buffer. - * \param buff single asio buffer - */ - void send(const boost::asio::const_buffer &buff); - - /*! - * Receive a buffer. The memory is managed internally. - * Calling recv will invalidate the buffer of the previous recv. - * \return a shared iovec with allocated memory - */ - uhd::shared_iovec recv(void); - -private: - boost::asio::ip::udp::socket *_socket; - boost::asio::ip::udp::endpoint _receiver_endpoint; - boost::asio::ip::udp::endpoint _sender_endpoint; - boost::asio::io_service _io_service; -}; - -}} //namespace - -#endif /* INCLUDED_UHD_TRANSPORT_UDP_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..40e60d091 --- /dev/null +++ b/host/include/uhd/transport/udp_simple.hpp @@ -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_TRANSPORT_UDP_SIMPLE_HPP +#define INCLUDED_UHD_TRANSPORT_UDP_SIMPLE_HPP + +#include <uhd/config.hpp> +#include <boost/asio.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; + + /*! + * 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 + * \return the number of bytes received or zero on timeout + */ + virtual size_t recv(const boost::asio::mutable_buffer &buff) = 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..03d89b3a5 --- /dev/null +++ b/host/include/uhd/transport/udp_zero_copy.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_TRANSPORT_UDP_ZERO_COPY_HPP +#define INCLUDED_UHD_TRANSPORT_UDP_ZERO_COPY_HPP + +#include <uhd/config.hpp> +#include <uhd/transport/smart_buffer.hpp> +#include <boost/asio.hpp> +#include <boost/utility.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() is called on the socket. + * Rather, the zero copy transport gives the caller a memory reference. + * 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 recv() call. + */ +class UHD_API udp_zero_copy : boost::noncopyable{ +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 + */ + static sptr make(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 a buffer. + * Blocks until data is received or a timeout occurs. + * The memory is managed by the implementation. + * \return a smart buffer (empty on timeout) + */ + virtual smart_buffer::sptr recv(void) = 0; +}; + +}} //namespace + +#endif /* INCLUDED_UHD_TRANSPORT_UDP_ZERO_COPY_HPP */ diff --git a/host/include/uhd/transport/vrt.hpp b/host/include/uhd/transport/vrt.hpp new file mode 100644 index 000000000..db2c57eba --- /dev/null +++ b/host/include/uhd/transport/vrt.hpp @@ -0,0 +1,71 @@ +// +// 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_HPP +#define INCLUDED_UHD_TRANSPORT_VRT_HPP + +#include <uhd/config.hpp> +#include <uhd/metadata.hpp> +#include <cstddef> + +namespace uhd{ namespace transport{ + +namespace vrt{ + + static const size_t max_header_words32 = 7; + + /*! + * Pack a vrt header from metadata. + * \param metadata the tx metadata with flags and timestamps + * \param header_buff memory to write the packed vrt header + * \param num_header_words32 number of words in the vrt header + * \param num_payload_words32 the length of the payload + * \param num_packet_words32 the length of the packet + * \param packet_count the packet count sequence number + */ + UHD_API void pack( + const tx_metadata_t &metadata, //input + boost::uint32_t *header_buff, //output + size_t &num_header_words32, //output + size_t num_payload_words32, //input + size_t &num_packet_words32, //output + size_t packet_count //input + ); + + /*! + * Unpack a vrt header to metadata. + * \param metadata the rx metadata with flags and timestamps + * \param header_buff memory to read the packed vrt header + * \param num_header_words32 number of words in the vrt header + * \param num_payload_words32 the length of the payload + * \param num_packet_words32 the length of the packet + * \param packet_count the packet count sequence number + */ + UHD_API void unpack( + rx_metadata_t &metadata, //output + const boost::uint32_t *header_buff, //input + size_t &num_header_words32, //output + size_t &num_payload_words32, //output + size_t num_packet_words32, //input + size_t &packet_count //output + ); + +} //namespace vrt + +}} //namespace + +#endif /* INCLUDED_UHD_TRANSPORT_VRT_HPP */ diff --git a/host/include/uhd/types.hpp b/host/include/uhd/types.hpp new file mode 100644 index 000000000..1439f57a1 --- /dev/null +++ b/host/include/uhd/types.hpp @@ -0,0 +1,83 @@ +// +// 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_HPP +#define INCLUDED_UHD_TYPES_HPP + +#include <uhd/config.hpp> +#include <string> + +namespace uhd{ + + typedef float gain_t; //TODO REMOVE + typedef double freq_t; //TODO REMOVE + + /*! + * 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); + }; + + /*! + * 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 DDC/DUC as + * the target and actual digital converter frequency. + * It also tell us weather or not the spectrum is inverted. + */ + struct UHD_API tune_result_t{ + double target_inter_freq; + double actual_inter_freq; + double target_dxc_freq; + double actual_dxc_freq; + bool spectrum_inverted; + tune_result_t(void); + }; + + /*! + * Clock configuration settings: + * The source for the 10MHz reference clock. + * The source and polarity for the PPS clock. + * Possible settings for the reference and pps source + * are implementation specific motherboard properties. + * See the MBOARD_PROP_XXX_SOURCE_NAMES properties. + */ + struct clock_config_t{ + enum polarity_t {POLARITY_NEG, POLARITY_POS}; + std::string ref_source; + std::string pps_source; + polarity_t pps_polarity; + clock_config_t(void); + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_HPP */ diff --git a/host/include/uhd/usrp/CMakeLists.txt b/host/include/uhd/usrp/CMakeLists.txt index e7bdc1784..4e0a92365 100644 --- a/host/include/uhd/usrp/CMakeLists.txt +++ b/host/include/uhd/usrp/CMakeLists.txt @@ -21,6 +21,7 @@ INSTALL(FILES dboard_id.hpp dboard_interface.hpp dboard_manager.hpp + usrp1e.hpp usrp2.hpp DESTINATION ${HEADER_DIR}/uhd/usrp ) diff --git a/host/include/uhd/usrp/dboard_base.hpp b/host/include/uhd/usrp/dboard_base.hpp index b5c0d40ed..907a7814a 100644 --- a/host/include/uhd/usrp/dboard_base.hpp +++ b/host/include/uhd/usrp/dboard_base.hpp @@ -18,6 +18,7 @@ #ifndef INCLUDED_UHD_USRP_DBOARD_BASE_HPP #define INCLUDED_UHD_USRP_DBOARD_BASE_HPP +#include <uhd/config.hpp> #include <uhd/wax.hpp> #include <boost/utility.hpp> #include <boost/shared_ptr.hpp> @@ -31,7 +32,7 @@ namespace uhd{ namespace usrp{ * A daughter board dboard_base class for all dboards. * Only other dboard dboard_base classes should inherit this. */ -class dboard_base : boost::noncopyable{ +class UHD_API dboard_base : boost::noncopyable{ public: typedef boost::shared_ptr<dboard_base> sptr; //the constructor args consist of a subdev name and an interface @@ -56,21 +57,22 @@ protected: dboard_id_t get_tx_id(void); private: - std::string _subdev_name; + std::string _subdev_name; dboard_interface::sptr _dboard_interface; - dboard_id_t _rx_id, _tx_id; + dboard_id_t _rx_id, _tx_id; }; /*! * A xcvr daughter board implements rx and tx methods * Sub classes for xcvr boards should inherit this. */ -class xcvr_dboard_base : public dboard_base{ +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 const&); + virtual ~xcvr_dboard_base(void); }; @@ -78,7 +80,7 @@ public: * A rx daughter board only implements rx methods. * Sub classes for rx-only boards should inherit this. */ -class rx_dboard_base : public dboard_base{ +class UHD_API rx_dboard_base : public dboard_base{ public: /*! * Create a new rx dboard object, override in subclasses. @@ -96,7 +98,7 @@ public: * A tx daughter board only implements tx methods. * Sub classes for rx-only boards should inherit this. */ -class tx_dboard_base : public dboard_base{ +class UHD_API tx_dboard_base : public dboard_base{ public: /*! * Create a new rx dboard object, override in subclasses. diff --git a/host/include/uhd/usrp/dboard_id.hpp b/host/include/uhd/usrp/dboard_id.hpp index 8e904ff33..4b2392bee 100644 --- a/host/include/uhd/usrp/dboard_id.hpp +++ b/host/include/uhd/usrp/dboard_id.hpp @@ -15,22 +15,23 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include <string> - #ifndef INCLUDED_UHD_USRP_DBOARD_ID_HPP #define INCLUDED_UHD_USRP_DBOARD_ID_HPP +#include <uhd/config.hpp> +#include <boost/cstdint.hpp> +#include <string> + namespace uhd{ namespace usrp{ -enum dboard_id_t{ - ID_NONE = 0xffff, - ID_BASIC_TX = 0x0000, - ID_BASIC_RX = 0x0001 -}; +typedef boost::uint16_t dboard_id_t; + +static const dboard_id_t ID_NONE = 0xffff; //TODO: REMOVE ME -struct dboard_id{ - static std::string to_string(const dboard_id_t &id); -}; +namespace dboard_id{ + static const dboard_id_t NONE = 0xffff; + UHD_API std::string to_string(const dboard_id_t &id); +} }} //namespace diff --git a/host/include/uhd/usrp/dboard_interface.hpp b/host/include/uhd/usrp/dboard_interface.hpp index 84e1f5b22..5b40616f0 100644 --- a/host/include/uhd/usrp/dboard_interface.hpp +++ b/host/include/uhd/usrp/dboard_interface.hpp @@ -18,9 +18,10 @@ #ifndef INCLUDED_UHD_USRP_DBOARD_INTERFACE_HPP #define INCLUDED_UHD_USRP_DBOARD_INTERFACE_HPP +#include <uhd/config.hpp> #include <boost/shared_ptr.hpp> +#include <boost/cstdint.hpp> #include <vector> -#include <stdint.h> namespace uhd{ namespace usrp{ @@ -30,10 +31,10 @@ namespace uhd{ namespace usrp{ * This dboard_interface provides i2c, spi, gpio, atr, aux dac/adc access. * Each mboard should have a specially tailored dboard dboard_interface. */ -class dboard_interface{ +class UHD_API dboard_interface{ public: typedef boost::shared_ptr<dboard_interface> sptr; - typedef std::vector<uint8_t> byte_vector_t; + typedef std::vector<boost::uint8_t> byte_vector_t; //tells the host which unit to use enum unit_type_t{ @@ -96,7 +97,7 @@ public: * \param rx_value 16-bits, 0=FPGA output low, 1=FPGA output high * \param mask 16-bits, 0=software, 1=atr */ - virtual void set_atr_reg(gpio_bank_t bank, uint16_t tx_value, uint16_t rx_value, uint16_t mask) = 0; + virtual void set_atr_reg(gpio_bank_t bank, boost::uint16_t tx_value, boost::uint16_t rx_value, boost::uint16_t mask) = 0; /*! * Set daughterboard GPIO data direction register. @@ -105,7 +106,7 @@ public: * \param value 16-bits, 0=FPGA input, 1=FPGA output * \param mask 16-bits, 0=ignore, 1=set */ - virtual void set_gpio_ddr(gpio_bank_t bank, uint16_t value, uint16_t mask) = 0; + virtual void set_gpio_ddr(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask) = 0; /*! * Set daughterboard GPIO pin values. @@ -114,7 +115,7 @@ public: * \param value 16 bits, 0=low, 1=high * \param mask 16 bits, 0=ignore, 1=set */ - virtual void write_gpio(gpio_bank_t bank, uint16_t value, uint16_t mask) = 0; + virtual void write_gpio(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask) = 0; /*! * Read daughterboard GPIO pin values @@ -122,7 +123,7 @@ public: * \param bank GPIO_TX_BANK or GPIO_RX_BANK * \return the value of the gpio bank */ - virtual uint16_t read_gpio(gpio_bank_t bank) = 0; + virtual boost::uint16_t read_gpio(gpio_bank_t bank) = 0; /*! * \brief Write to I2C peripheral diff --git a/host/include/uhd/usrp/dboard_manager.hpp b/host/include/uhd/usrp/dboard_manager.hpp index 042947ac4..6a105d1de 100644 --- a/host/include/uhd/usrp/dboard_manager.hpp +++ b/host/include/uhd/usrp/dboard_manager.hpp @@ -18,6 +18,7 @@ #ifndef INCLUDED_UHD_USRP_DBOARD_MANAGER_HPP #define INCLUDED_UHD_USRP_DBOARD_MANAGER_HPP +#include <uhd/config.hpp> #include <uhd/props.hpp> #include <uhd/usrp/dboard_base.hpp> #include <uhd/usrp/dboard_id.hpp> @@ -31,7 +32,7 @@ namespace uhd{ namespace usrp{ * Create subdev instances for each subdev on a dboard. * Provide wax::obj access to the subdevs inside. */ -class dboard_manager : boost::noncopyable{ +class UHD_API dboard_manager : boost::noncopyable{ public: typedef boost::shared_ptr<dboard_manager> sptr; @@ -40,15 +41,17 @@ public: typedef dboard_base::sptr(*dboard_ctor_t)(dboard_base::ctor_args_t const&); /*! - * Register subdevices for a given dboard id. + * Register a dboard into the system. * * \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_subdevs( + static void register_dboard( dboard_id_t dboard_id, dboard_ctor_t dboard_ctor, + const std::string &name, const prop_names_t &subdev_names ); diff --git a/host/include/uhd/usrp/usrp1e.hpp b/host/include/uhd/usrp/usrp1e.hpp new file mode 100644 index 000000000..f4cc39d8e --- /dev/null +++ b/host/include/uhd/usrp/usrp1e.hpp @@ -0,0 +1,55 @@ +// +// 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_USRP1E_HPP +#define INCLUDED_UHD_USRP_USRP1E_HPP + +#include <uhd/config.hpp> +#include <uhd/device.hpp> + +namespace uhd{ namespace usrp{ + +/*! + * The usrp1e device class. + */ +class UHD_API usrp1e : public device{ +public: + /*! + * Discover usrp1e devices on the system via the device node. + * This static method will be called by the device::discover. + * \param hint a device addr with the usrp1e address filled in + * \return a vector of device addresses for all usrp1es found + */ + static device_addrs_t discover(const device_addr_t &hint); + + /*! + * Make a usrp1e from a device address. + * \param addr the device address + * \return a device sptr to a new usrp1e + */ + static device::sptr make(const device_addr_t &addr); + + /*! + * Load the FPGA with an image file. + * \param bin_file the name of the fpga image file + */ + static void load_fpga(const std::string &bin_file); +}; + +}} //namespace + +#endif /* INCLUDED_UHD_USRP_USRP1E_HPP */ diff --git a/host/include/uhd/usrp/usrp2.hpp b/host/include/uhd/usrp/usrp2.hpp index f6e49cbd6..277ddc131 100644 --- a/host/include/uhd/usrp/usrp2.hpp +++ b/host/include/uhd/usrp/usrp2.hpp @@ -15,9 +15,10 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#ifndef INCLUDED_UHD_USRP_MBOARD_USRP2_HPP -#define INCLUDED_UHD_USRP_MBOARD_USRP2_HPP +#ifndef INCLUDED_UHD_USRP_USRP2_HPP +#define INCLUDED_UHD_USRP_USRP2_HPP +#include <uhd/config.hpp> #include <uhd/device.hpp> namespace uhd{ namespace usrp{ @@ -25,10 +26,15 @@ namespace uhd{ namespace usrp{ /*! * The usrp2 device class. */ -class usrp2 : public device{ +class UHD_API usrp2 : public device{ public: /*! * Discover usrp2 devices over the ethernet. + * + * Recommended key/value pairs for the device hint address: + * hint["addr"] = address, where address is a resolvable address + * or ip address, which may or may not be a broadcast address. + * * This static method will be called by the device::discover. * \param hint a device addr with the usrp2 address filled in * \return a vector of device addresses for all usrp2s found @@ -37,6 +43,11 @@ public: /*! * Make a usrp2 from a device address. + * + * Required key/value pairs for the device address: + * hint["addr"] = address, where address is a resolvable address + * or ip address, which must be the specific address of a usrp2. + * * \param addr the device address * \return a device sptr to a new usrp2 */ @@ -45,4 +56,4 @@ public: }} //namespace -#endif /* INCLUDED_UHD_USRP_MBOARD_USRP2_HPP */ +#endif /* INCLUDED_UHD_USRP_USRP2_HPP */ diff --git a/host/include/uhd/utils.hpp b/host/include/uhd/utils.hpp index 4331aba7e..e5333539f 100644 --- a/host/include/uhd/utils.hpp +++ b/host/include/uhd/utils.hpp @@ -15,17 +15,28 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include <uhd/wax.hpp> -#include <boost/foreach.hpp> +#ifndef INCLUDED_UHD_UTILS_HPP +#define INCLUDED_UHD_UTILS_HPP + +#include <uhd/config.hpp> #include <boost/format.hpp> -#include <boost/function.hpp> +#include <boost/current_function.hpp> #include <stdexcept> #include <algorithm> -#include <vector> -#include <map> -#ifndef INCLUDED_UHD_UTILS_HPP -#define INCLUDED_UHD_UTILS_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 STATIC_INSTANCE(_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 STATIC_BLOCK(_x) static struct _x{_x();}_x;_x::_x() /*! * Useful templated functions and classes that I like to pretend are part of stl @@ -40,7 +51,9 @@ namespace std{ }; #define ASSERT_THROW(_x) if (not (_x)) { \ - throw std::assert_error("Assertion Failed: " + std::string(#_x)); \ + throw std::assert_error(str(boost::format( \ + "Assertion Failed:\n %s:%d\n %s\n ---> %s <---" \ + ) % __FILE__ % __LINE__ % BOOST_CURRENT_FUNCTION % std::string(#_x))); \ } template<class T, class InputIterator, class Function> @@ -52,14 +65,19 @@ namespace std{ return tmp; } + template<class T, class Iterable, class Function> + T reduce(Iterable iterable, Function fcn, T init = 0){ + return reduce(iterable.begin(), iterable.end(), fcn, init); + } + template<class T, class InputIterator> bool has(InputIterator first, InputIterator last, const T &elem){ return last != std::find(first, last, elem); } - template<class T> - T sum(const T &a, const T &b){ - return a + b; + template<class T, class Iterable> + bool has(const Iterable &iterable, const T &elem){ + return has(iterable.begin(), iterable.end(), elem); } template<typename T> T signum(T n){ @@ -70,52 +88,43 @@ namespace std{ }//namespace std -/*namespace uhd{ - -inline void tune( - freq_t target_freq, - freq_t lo_offset, - wax::obj subdev_freq_proxy, - bool subdev_quadrature, - bool subdev_spectrum_inverted, - bool subdev_is_tx, - wax::obj dsp_freq_proxy, - freq_t dsp_sample_rate -){ - // Ask the d'board to tune as closely as it can to target_freq+lo_offset - subdev_freq_proxy = target_freq + lo_offset; - freq_t inter_freq = wax::cast<freq_t>(subdev_freq_proxy); - - // Calculate the DDC setting that will downconvert the baseband from the - // daughterboard to our target frequency. - freq_t delta_freq = target_freq - inter_freq; - freq_t delta_sign = std::signum(delta_freq); - delta_freq *= delta_sign; - delta_freq = fmod(delta_freq, dsp_sample_rate); - bool inverted = delta_freq > dsp_sample_rate/2.0; - freq_t dxc_freq = inverted? (delta_freq - dsp_sample_rate) : (-delta_freq); - dxc_freq *= delta_sign; - - // If the spectrum is inverted, and the daughterboard doesn't do - // quadrature downconversion, we can fix the inversion by flipping the - // sign of the dxc_freq... (This only happens using the basic_rx board) - if (subdev_spectrum_inverted){ - inverted = not inverted; - } - if (inverted and not subdev_quadrature){ - dxc_freq = -dxc_freq; - inverted = not inverted; - } - if (subdev_is_tx){ - dxc_freq = -dxc_freq; // down conversion versus up conversion +#include <boost/format.hpp> +#include <boost/foreach.hpp> +#include <boost/lexical_cast.hpp> + +namespace uhd{ + + /*! + * 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 iterable a list of possible settings + * \param elem an element that may be in the list + * \param what a description of what is being set + * \throw assertion_error when elem not in list + */ + template<class T, class Iterable> void assert_has( + const Iterable &iterable, + const T &elem, + const std::string &what = "unknown" + ){ + if (std::has(iterable, elem)) return; + std::string possible_values = ""; + BOOST_FOREACH(T e, iterable){ + if (e != iterable.begin()[0]) possible_values += ", "; + possible_values += boost::lexical_cast<std::string>(e); + } + throw std::assert_error(str(boost::format( + "Error: %s is not a valid %s. " + "Possible values are: [%s]." + ) + % boost::lexical_cast<std::string>(elem) + % what % possible_values + )); } - dsp_freq_proxy = dxc_freq; - //freq_t actual_dxc_freq = wax::cast<freq_t>(dsp_freq_proxy); - - //return some kind of tune result tuple/struct -} - -} //namespace uhd*/ +}//namespace uhd #endif /* INCLUDED_UHD_UTILS_HPP */ diff --git a/host/include/uhd/wax.hpp b/host/include/uhd/wax.hpp index 1d5054351..30645f491 100644 --- a/host/include/uhd/wax.hpp +++ b/host/include/uhd/wax.hpp @@ -18,33 +18,37 @@ #ifndef INCLUDED_WAX_HPP #define INCLUDED_WAX_HPP +#include <uhd/config.hpp> #include <boost/any.hpp> -#include <iostream> /*! * WAX - it's a metaphor! * - * The WAX framework allows object to have generic/anyobj properties. + * The WAX framework allows an object to have generic/anyobj properties. * These properties can be addressed through generic/anyobj identifiers. - * A property of a WAX object may even be another WAX object. * - * When a property is a WAX object, the returned value must be an obj pointer. - * A WAX object provides two objs of pointers: obj::ptr and obj::sptr. - * The choice of pointer vs smart pointer depends on the owner of the memory. + * 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] + * my_obj[prop1][prop2][prop3] = value; + * value = my_obj[prop1][prop2][prop3].as<type>(); * - * Any value returned from an access operation is of wax::obj. - * To use this value, it must be cast with wax::cast<new_obj>(value). + * 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(). */ 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: @@ -56,7 +60,7 @@ namespace wax{ * For property nesting, wax obj subclasses return special links * to other wax obj subclasses, and the api handles the magic. */ - class obj{ + class UHD_API obj{ public: /*! @@ -124,6 +128,17 @@ namespace wax{ */ 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 &); @@ -137,31 +152,12 @@ namespace wax{ * \return a boost any type with contents */ boost::any resolve(void) const; - template<class T> friend T cast(const obj &); //private contents of this obj boost::any _contents; }; - /*! - * The wax::bad cast will be thrown when - * cast is called with the wrong typeid. - */ - typedef boost::bad_any_cast bad_cast; - - /*! - * Cast a wax::obj into the desired obj. - * Usage wax::cast<new_obj>(my_value). - * - * \param val the obj to cast - * \return an object of the desired type - * \throw wax::bad_cast when the cast fails - */ - template<class T> T cast(const obj &val){ - return boost::any_cast<T>(val.resolve()); - } - } //namespace wax #endif /* INCLUDED_WAX_HPP */ |