diff options
39 files changed, 591 insertions, 245 deletions
diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index 60af3d0a1..2f5d03f7d 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -58,17 +58,22 @@ IF(UNIX) UHD_ADD_OPTIONAL_CXX_COMPILER_FLAG(-Wextra HAVE_WEXTRA) UHD_ADD_OPTIONAL_CXX_COMPILER_FLAG(-pedantic HAVE_PEDANTIC) UHD_ADD_OPTIONAL_CXX_COMPILER_FLAG(-ansi HAVE_ANSI) + #only export symbols that are declared to be part of the uhd api: + UHD_ADD_OPTIONAL_CXX_COMPILER_FLAG(-fvisibility=hidden HAVE_VISIBILITY_HIDDEN) ENDIF(UNIX) IF(WIN32) ADD_DEFINITIONS(-Dnot=! -Dand=&& -Dor=||) #logical operators - ADD_DEFINITIONS(-D_WIN32_WINNT=0x0501) #as requested by vs + ADD_DEFINITIONS(-D_WIN32_WINNT=0x0501) #minimum version required is windows xp ADD_DEFINITIONS(-DNOMINMAX) #disables stupidity and enables std::min and std::max + ADD_DEFINITIONS(-D_SCL_SECURE_NO_WARNINGS) #avoid warnings from boost::split + ADD_DEFINITIONS(-DBOOST_ALL_DYN_LINK) #setup boost auto-linking in msvc ENDIF(WIN32) ######################################################################## # Setup Boost ######################################################################## +SET(Boost_ADDITIONAL_VERSIONS "1.42.0" "1.42") FIND_PACKAGE(Boost 1.36 REQUIRED date_time filesystem diff --git a/host/include/uhd/CMakeLists.txt b/host/include/uhd/CMakeLists.txt index 522f43afd..3d00462cf 100644 --- a/host/include/uhd/CMakeLists.txt +++ b/host/include/uhd/CMakeLists.txt @@ -20,6 +20,7 @@ ADD_SUBDIRECTORY(transport) ADD_SUBDIRECTORY(usrp) INSTALL(FILES + config.hpp device.hpp device_addr.hpp dict.hpp @@ -28,6 +29,7 @@ INSTALL(FILES props.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 c9d608bcf..13b40febe 100644 --- a/host/include/uhd/device.hpp +++ b/host/include/uhd/device.hpp @@ -18,6 +18,7 @@ #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> @@ -33,7 +34,7 @@ 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; @@ -76,11 +77,6 @@ public: static sptr make(const device_addr_t &hint, size_t which = 0); /*! - * Get the device address for this board. - */ - device_addr_t get_device_addr(void); - - /*! * Send a buffer containing IF data with its metadata. * * Send handles fragmentation as follows: diff --git a/host/include/uhd/device_addr.hpp b/host/include/uhd/device_addr.hpp index 1b624b770..7673faff0 100644 --- a/host/include/uhd/device_addr.hpp +++ b/host/include/uhd/device_addr.hpp @@ -18,6 +18,7 @@ #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> @@ -30,7 +31,7 @@ namespace uhd{ * Wrapper for an ethernet mac address. * Provides conversion between string and binary formats. */ - struct mac_addr_t{ + 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,13 +57,13 @@ namespace uhd{ * \return the string representation */ namespace device_addr{ - std::string to_string(const device_addr_t &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 8f7cd5a0f..f08493952 100644 --- a/host/include/uhd/dict.hpp +++ b/host/include/uhd/dict.hpp @@ -40,6 +40,19 @@ namespace uhd{ } /*! + * Input iterator constructor: + * Makes boost::assign::map_list_of work. + * \param first the begin iterator + * \param last the end iterator + */ + template <class InputIterator> + dict(InputIterator first, InputIterator last){ + for(InputIterator it = first; it != last; it++){ + _map.push_back(*it); + } + } + + /*! * Destroy this dict. */ ~dict(void){ diff --git a/host/include/uhd/gain_handler.hpp b/host/include/uhd/gain_handler.hpp index a71d63c84..65d6cecf9 100644 --- a/host/include/uhd/gain_handler.hpp +++ b/host/include/uhd/gain_handler.hpp @@ -15,16 +15,17 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // +#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> -#ifndef INCLUDED_UHD_GAIN_HANDLER_HPP -#define INCLUDED_UHD_GAIN_HANDLER_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; @@ -32,7 +33,7 @@ public: /*! * A set of properties for dealing with gains. */ - struct props_t{ + struct UHD_API props_t{ wax::obj value, range, names; props_t(void); //default constructor }; diff --git a/host/include/uhd/metadata.hpp b/host/include/uhd/metadata.hpp index ce72ff14b..6d80f070d 100644 --- a/host/include/uhd/metadata.hpp +++ b/host/include/uhd/metadata.hpp @@ -18,6 +18,7 @@ #ifndef INCLUDED_UHD_METADATA_HPP #define INCLUDED_UHD_METADATA_HPP +#include <uhd/config.hpp> #include <uhd/time_spec.hpp> namespace uhd{ @@ -27,7 +28,7 @@ namespace uhd{ * Includes stream ID, time specification, and fragmentation flags. * The receive routines will convert IF data headers into metadata. */ -struct rx_metadata_t{ +struct UHD_API rx_metadata_t{ boost::uint32_t stream_id; time_spec_t time_spec; bool has_stream_id; @@ -43,7 +44,7 @@ struct rx_metadata_t{ * Includes stream ID, time specification, and burst flags. * The send routines will convert the metadata to IF data headers. */ -struct tx_metadata_t{ +struct UHD_API tx_metadata_t{ boost::uint32_t stream_id; time_spec_t time_spec; bool has_stream_id; diff --git a/host/include/uhd/props.hpp b/host/include/uhd/props.hpp index 6d4414d3a..41e0eff63 100644 --- a/host/include/uhd/props.hpp +++ b/host/include/uhd/props.hpp @@ -15,36 +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; - - //gain range tuple (min, max, step) - typedef boost::tuple<gain_t, gain_t, gain_t> gain_range_t; - - //freq range tuple (min, max) - typedef boost::tuple<freq_t, freq_t> freq_range_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; @@ -55,7 +35,8 @@ 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 key.as<named_prop_t>(); } @@ -94,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 diff --git a/host/include/uhd/simple_device.hpp b/host/include/uhd/simple_device.hpp index c43155ff2..ad25eccdc 100644 --- a/host/include/uhd/simple_device.hpp +++ b/host/include/uhd/simple_device.hpp @@ -15,40 +15,25 @@ // 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 <uhd/device.hpp> #include <vector> -#ifndef INCLUDED_UHD_SIMPLE_DEVICE_HPP -#define INCLUDED_UHD_SIMPLE_DEVICE_HPP - 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 DDC/DUC as - * the target and actual digital converter frequency. - * It also tell us weather or not the spectrum is inverted. - */ -struct 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); -}; - -/*! * 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 simple_device : boost::noncopyable{ +class UHD_API simple_device : boost::noncopyable{ public: typedef boost::shared_ptr<simple_device> sptr; static sptr make(const std::string &args); @@ -71,11 +56,11 @@ public: virtual std::vector<double> get_rx_rates(void) = 0; virtual tune_result_t set_rx_freq(double freq) = 0; - virtual std::vector<double> get_rx_freq_range(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 std::vector<float> get_rx_gain_range(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; @@ -89,11 +74,11 @@ public: virtual std::vector<double> get_tx_rates(void) = 0; virtual tune_result_t set_tx_freq(double freq) = 0; - virtual std::vector<double> get_tx_freq_range(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 std::vector<float> get_tx_gain_range(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; diff --git a/host/include/uhd/time_spec.hpp b/host/include/uhd/time_spec.hpp index 588758824..c1e7cf3a1 100644 --- a/host/include/uhd/time_spec.hpp +++ b/host/include/uhd/time_spec.hpp @@ -15,12 +15,13 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include <boost/date_time/posix_time/posix_time.hpp> -#include <boost/cstdint.hpp> - #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{ /*! @@ -29,7 +30,7 @@ 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{ + struct UHD_API time_spec_t{ boost::uint32_t secs; boost::uint32_t ticks; diff --git a/host/include/uhd/transport/smart_buffer.hpp b/host/include/uhd/transport/smart_buffer.hpp index 914c02f50..9e1032feb 100644 --- a/host/include/uhd/transport/smart_buffer.hpp +++ b/host/include/uhd/transport/smart_buffer.hpp @@ -15,13 +15,13 @@ // 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> -#ifndef INCLUDED_UHD_TRANSPORT_SMART_BUFFER_HPP -#define INCLUDED_UHD_TRANSPORT_SMART_BUFFER_HPP - namespace uhd{ namespace transport{ /*! diff --git a/host/include/uhd/transport/udp_simple.hpp b/host/include/uhd/transport/udp_simple.hpp index 0d8fcc5f0..40e60d091 100644 --- a/host/include/uhd/transport/udp_simple.hpp +++ b/host/include/uhd/transport/udp_simple.hpp @@ -15,16 +15,17 @@ // 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> -#ifndef INCLUDED_UHD_TRANSPORT_UDP_SIMPLE_HPP -#define INCLUDED_UHD_TRANSPORT_UDP_SIMPLE_HPP - namespace uhd{ namespace transport{ -class udp_simple : boost::noncopyable{ +class UHD_API udp_simple : boost::noncopyable{ public: typedef boost::shared_ptr<udp_simple> sptr; diff --git a/host/include/uhd/transport/udp_zero_copy.hpp b/host/include/uhd/transport/udp_zero_copy.hpp index 1a8d822fd..03d89b3a5 100644 --- a/host/include/uhd/transport/udp_zero_copy.hpp +++ b/host/include/uhd/transport/udp_zero_copy.hpp @@ -15,14 +15,15 @@ // 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> -#ifndef INCLUDED_UHD_TRANSPORT_UDP_ZERO_COPY_HPP -#define INCLUDED_UHD_TRANSPORT_UDP_ZERO_COPY_HPP - namespace uhd{ namespace transport{ /*! @@ -35,7 +36,7 @@ namespace uhd{ namespace transport{ * If no platform specific solution is available, make returns a boost asio * implementation that wraps the functionality around a standard recv() call. */ -class udp_zero_copy : boost::noncopyable{ +class UHD_API udp_zero_copy : boost::noncopyable{ public: typedef boost::shared_ptr<udp_zero_copy> sptr; diff --git a/host/include/uhd/transport/vrt.hpp b/host/include/uhd/transport/vrt.hpp index 3b5bf41bf..db2c57eba 100644 --- a/host/include/uhd/transport/vrt.hpp +++ b/host/include/uhd/transport/vrt.hpp @@ -15,12 +15,13 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include <uhd/metadata.hpp> -#include <cstddef> - #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{ @@ -36,7 +37,7 @@ namespace vrt{ * \param num_packet_words32 the length of the packet * \param packet_count the packet count sequence number */ - void pack( + UHD_API void pack( const tx_metadata_t &metadata, //input boost::uint32_t *header_buff, //output size_t &num_header_words32, //output @@ -54,7 +55,7 @@ namespace vrt{ * \param num_packet_words32 the length of the packet * \param packet_count the packet count sequence number */ - void unpack( + UHD_API void unpack( rx_metadata_t &metadata, //output const boost::uint32_t *header_buff, //input size_t &num_header_words32, //output 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/dboard_base.hpp b/host/include/uhd/usrp/dboard_base.hpp index 9048344ac..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 @@ -65,7 +66,7 @@ private: * 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. @@ -79,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. @@ -97,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 370cd1fbb..4b2392bee 100644 --- a/host/include/uhd/usrp/dboard_id.hpp +++ b/host/include/uhd/usrp/dboard_id.hpp @@ -15,12 +15,13 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // -#include <boost/cstdint.hpp> -#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{ typedef boost::uint16_t dboard_id_t; @@ -29,7 +30,7 @@ static const dboard_id_t ID_NONE = 0xffff; //TODO: REMOVE ME namespace dboard_id{ static const dboard_id_t NONE = 0xffff; - std::string to_string(const dboard_id_t &id); + 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 b00643550..5b40616f0 100644 --- a/host/include/uhd/usrp/dboard_interface.hpp +++ b/host/include/uhd/usrp/dboard_interface.hpp @@ -18,6 +18,7 @@ #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> @@ -30,7 +31,7 @@ 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<boost::uint8_t> byte_vector_t; diff --git a/host/include/uhd/usrp/dboard_manager.hpp b/host/include/uhd/usrp/dboard_manager.hpp index 0c32c6dba..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; diff --git a/host/include/uhd/usrp/usrp1e.hpp b/host/include/uhd/usrp/usrp1e.hpp index 60a6a191a..f4cc39d8e 100644 --- a/host/include/uhd/usrp/usrp1e.hpp +++ b/host/include/uhd/usrp/usrp1e.hpp @@ -18,6 +18,7 @@ #ifndef INCLUDED_UHD_USRP_USRP1E_HPP #define INCLUDED_UHD_USRP_USRP1E_HPP +#include <uhd/config.hpp> #include <uhd/device.hpp> namespace uhd{ namespace usrp{ @@ -25,7 +26,7 @@ namespace uhd{ namespace usrp{ /*! * The usrp1e device class. */ -class usrp1e : public device{ +class UHD_API usrp1e : public device{ public: /*! * Discover usrp1e devices on the system via the device node. diff --git a/host/include/uhd/usrp/usrp2.hpp b/host/include/uhd/usrp/usrp2.hpp index b13786546..277ddc131 100644 --- a/host/include/uhd/usrp/usrp2.hpp +++ b/host/include/uhd/usrp/usrp2.hpp @@ -18,6 +18,7 @@ #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,7 +26,7 @@ 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. diff --git a/host/include/uhd/utils.hpp b/host/include/uhd/utils.hpp index 995cb9926..e5333539f 100644 --- a/host/include/uhd/utils.hpp +++ b/host/include/uhd/utils.hpp @@ -18,10 +18,11 @@ #ifndef INCLUDED_UHD_UTILS_HPP #define INCLUDED_UHD_UTILS_HPP -#include <stdexcept> -#include <algorithm> +#include <uhd/config.hpp> #include <boost/format.hpp> #include <boost/current_function.hpp> +#include <stdexcept> +#include <algorithm> /*! * Defines a function that implements the "construct on first use" idiom diff --git a/host/include/uhd/wax.hpp b/host/include/uhd/wax.hpp index 0291a06b7..30645f491 100644 --- a/host/include/uhd/wax.hpp +++ b/host/include/uhd/wax.hpp @@ -18,6 +18,7 @@ #ifndef INCLUDED_WAX_HPP #define INCLUDED_WAX_HPP +#include <uhd/config.hpp> #include <boost/any.hpp> /*! @@ -59,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: /*! diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index e547fef85..a7dded86b 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -22,9 +22,11 @@ SET(libuhd_sources device.cpp device_addr.cpp gain_handler.cpp + load_modules.cpp metadata.cpp simple_device.cpp time_spec.cpp + types.cpp wax.cpp transport/udp_simple.cpp transport/vrt.cpp @@ -44,7 +46,7 @@ SET(libuhd_sources # Conditionally add the udp sources ######################################################################## LIST(APPEND libuhd_sources - transport/udp_zero_copy_none.cpp + transport/udp_zero_copy_asio.cpp ) ######################################################################## @@ -78,13 +80,34 @@ ELSE(HAS_USRP1E_REQUIRED_HEADERS) ENDIF(HAS_USRP1E_REQUIRED_HEADERS) ######################################################################## +# Setup defines for module loading +######################################################################## +INCLUDE(CheckIncludeFileCXX) + +CHECK_INCLUDE_FILE_CXX(dlfcn.h HAVE_DLFCN_H) +CHECK_INCLUDE_FILE_CXX(Winbase.h HAVE_WINBASE_H) + +IF(HAVE_DLFCN_H) + MESSAGE(STATUS "Module loading supported through dlopen...") + ADD_DEFINITIONS(-DHAVE_DLFCN_H) +ELSEIF(HAVE_WINBASE_H) + MESSAGE(STATUS "Module loading supported through LoadLibrary...") + ADD_DEFINITIONS(-DHAVE_WINBASE_H) +ELSE(HAVE_DLFCN_H) + MESSAGE(STATUS "Module loading not supported...") +ENDIF(HAVE_DLFCN_H) + +######################################################################## # Setup libuhd library ######################################################################## ADD_LIBRARY(uhd SHARED ${libuhd_sources}) -TARGET_LINK_LIBRARIES(uhd ${Boost_LIBRARIES}) +TARGET_LINK_LIBRARIES(uhd ${Boost_LIBRARIES} ${CMAKE_DL_LIBS}) + +SET_TARGET_PROPERTIES(uhd PROPERTIES DEFINE_SYMBOL "UHD_DLL_EXPORTS") INSTALL(TARGETS uhd - LIBRARY DESTINATION ${LIBRARY_DIR} - ARCHIVE DESTINATION ${LIBRARY_DIR} + LIBRARY DESTINATION ${LIBRARY_DIR} # .so file + ARCHIVE DESTINATION ${LIBRARY_DIR} # .lib file + RUNTIME DESTINATION ${LIBRARY_DIR} # .dll file ) diff --git a/host/lib/gain_handler.cpp b/host/lib/gain_handler.cpp index 847bc0528..7dd1547cb 100644 --- a/host/lib/gain_handler.cpp +++ b/host/lib/gain_handler.cpp @@ -17,10 +17,12 @@ #include <uhd/gain_handler.hpp> #include <uhd/utils.hpp> +#include <uhd/types.hpp> #include <uhd/props.hpp> #include <boost/assign/list_of.hpp> #include <boost/foreach.hpp> #include <boost/format.hpp> +#include <cmath> #include <vector> using namespace uhd; @@ -99,12 +101,10 @@ gain_t gain_handler_impl::get_overall_gain_val(void){ gain_range_t gain_handler_impl::get_overall_gain_range(void){ gain_t gain_min = 0, gain_max = 0, gain_step = 0; BOOST_FOREACH(std::string name, get_gain_names()){ - gain_t gain_min_tmp, gain_max_tmp, gain_step_tmp; - boost::tie(gain_min_tmp, gain_max_tmp, gain_step_tmp) = \ - get_named_prop<gain_range_t>(_props.range, name); - gain_min += gain_min_tmp; - gain_max += gain_max_tmp; - gain_step = std::max(gain_step, gain_step_tmp); + gain_range_t gain_tmp = get_named_prop<gain_range_t>(_props.range, name); + gain_min += gain_tmp.min; + gain_max += gain_tmp.max; + gain_step = std::max(gain_step, gain_tmp.step); } return gain_range_t(gain_min, gain_max, gain_step); } @@ -150,12 +150,10 @@ bool gain_handler_impl::intercept_set(const wax::obj &key_, const wax::obj &val) //not a wildcard... dont handle (but check name and range) if (name != ""){ assert_has(get_gain_names(), name, "gain name"); - gain_t gain_min, gain_max, gain_step; - boost::tie(gain_min, gain_max, gain_step) = \ - get_named_prop<gain_range_t>(_props.range, name); - if (gain_val > gain_max or gain_val < gain_min) throw std::range_error(str( + gain_range_t gain = get_named_prop<gain_range_t>(_props.range, name); + if (gain_val > gain.max or gain_val < gain.min) throw std::range_error(str( boost::format("A value of %f for gain %s is out of range of (%f, %f)") - % gain_val % name % gain_min % gain_max + % gain_val % name % gain.min % gain.max )); return false; } @@ -163,14 +161,12 @@ bool gain_handler_impl::intercept_set(const wax::obj &key_, const wax::obj &val) //set the overall gain BOOST_FOREACH(std::string name, get_gain_names()){ //get the min, max, step for this gain name - gain_t gain_min, gain_max, gain_step; - boost::tie(gain_min, gain_max, gain_step) = \ - get_named_prop<gain_range_t>(_props.range, name); + gain_range_t gain = get_named_prop<gain_range_t>(_props.range, name); //clip g to be within the allowed range - gain_t g = std::min(std::max(gain_val, gain_min), gain_max); + gain_t g = std::min(std::max(gain_val, gain.min), gain.max); //set g to be a multiple of the step size - g -= fmod(g, gain_step); + g -= std::fmod(g, gain.step); //set g to be the new gain _link[named_prop_t(_props.value, name)] = g; //subtract g out of the total gain left to apply diff --git a/host/lib/load_modules.cpp b/host/lib/load_modules.cpp new file mode 100644 index 000000000..700afcd3f --- /dev/null +++ b/host/lib/load_modules.cpp @@ -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/>. +// + +#include <uhd/utils.hpp> +#include <boost/format.hpp> +#include <boost/foreach.hpp> +#include <boost/algorithm/string.hpp> +#include <boost/filesystem.hpp> +#include <iostream> +#include <stdexcept> +#include <cstdlib> + +namespace fs = boost::filesystem; + +/*********************************************************************** + * Module Load Function + **********************************************************************/ +#ifdef HAVE_DLFCN_H +#include <dlfcn.h> + +static void load_module(const std::string &file_name){ + if (dlopen(file_name.c_str(), RTLD_LAZY) == NULL){ + throw std::runtime_error(str( + boost::format("dlopen failed to load \"%s\"") % file_name + )); + } +} + +#elif HAVE_WINBASE_H +#include <Winbase.h> + +static void load_module(const std::string &file_name){ + if (LoadLibrary(file_name.c_str()) == NULL){ + throw std::runtime_error(str( + boost::format("LoadLibrary failed to load \"%s\"") % file_name + )); + } +} + +#else + +static void load_module(const std::string &file_name){ + throw std::runtime_error(str( + boost::format("Module loading not supported: Cannot load \"%s\"") % file_name + )); +} + +#endif + +/*********************************************************************** + * Load Modules + **********************************************************************/ +/*! + * Load all modules in a given path. + * This will recurse into sub-directories. + * Does not throw, prints to std error. + * \param path the filesystem path + */ +static void load_path(const fs::path &path){ + if (not fs::exists(path)){ + std::cerr << boost::format("Module path \"%s\" not found.") % path.file_string() << std::endl; + return; + } + + //try to load the files in this path + if (fs::is_directory(path)){ + for( + fs::directory_iterator dir_itr(path); + dir_itr != fs::directory_iterator(); + ++dir_itr + ){ + load_path(dir_itr->path()); + } + return; + } + + //its not a directory, try to load it + try{ + load_module(path.file_string()); + } + catch(const std::exception &err){ + std::cerr << boost::format("Error: %s") % err.what() << std::endl; + } +} + +/*! + * Load all the modules given by the module path enviroment variable. + * The path variable may be several paths split by path separators. + */ +STATIC_BLOCK(load_modules){ + //get the environment variable module path + char *env_module_path = std::getenv("UHD_MODULE_PATH"); + if (env_module_path == NULL) return; + + //split the path at the path separators + std::vector<std::string> module_paths; + boost::split(module_paths, env_module_path, boost::is_any_of(":;")); + + //load modules in each path + BOOST_FOREACH(const std::string &module_path, module_paths){ + load_path(fs::system_complete(fs::path(module_path))); + } +} diff --git a/host/lib/simple_device.cpp b/host/lib/simple_device.cpp index 79b035071..ba1966e0d 100644 --- a/host/lib/simple_device.cpp +++ b/host/lib/simple_device.cpp @@ -19,18 +19,14 @@ #include <uhd/device.hpp> #include <uhd/utils.hpp> #include <uhd/props.hpp> +#include <uhd/types.hpp> #include <boost/algorithm/string.hpp> -#include <boost/algorithm/string/trim.hpp> #include <boost/foreach.hpp> #include <boost/format.hpp> #include <stdexcept> using namespace uhd; -tune_result_t::tune_result_t(void){ - /* NOP */ -} - /*********************************************************************** * Tune Helper Function **********************************************************************/ @@ -196,11 +192,8 @@ public: return tune(target_freq, lo_offset, _rx_subdev, _rx_ddc, false/* not tx */); } - std::vector<double> get_rx_freq_range(void){ - std::vector<double> range(2); - boost::tie(range[0], range[1]) = \ - _rx_subdev[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(); - return range; + freq_range_t get_rx_freq_range(void){ + return _rx_subdev[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(); } void set_rx_gain(float gain){ @@ -211,11 +204,8 @@ public: return _rx_subdev[SUBDEV_PROP_GAIN].as<gain_t>(); } - std::vector<float> get_rx_gain_range(void){ - std::vector<float> range(3); - boost::tie(range[0], range[1], range[2]) = \ - _rx_subdev[SUBDEV_PROP_GAIN_RANGE].as<gain_range_t>(); - return range; + gain_range_t get_rx_gain_range(void){ + return _rx_subdev[SUBDEV_PROP_GAIN_RANGE].as<gain_range_t>(); } void set_rx_antenna(const std::string &ant){ @@ -258,11 +248,8 @@ public: return tune(target_freq, lo_offset, _tx_subdev, _tx_duc, true/* is tx */); } - std::vector<double> get_tx_freq_range(void){ - std::vector<double> range(2); - boost::tie(range[0], range[1]) = \ - _tx_subdev[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(); - return range; + freq_range_t get_tx_freq_range(void){ + return _tx_subdev[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(); } void set_tx_gain(float gain){ @@ -273,11 +260,8 @@ public: return _tx_subdev[SUBDEV_PROP_GAIN].as<gain_t>(); } - std::vector<float> get_tx_gain_range(void){ - std::vector<float> range(3); - boost::tie(range[0], range[1], range[2]) = \ - _tx_subdev[SUBDEV_PROP_GAIN_RANGE].as<gain_range_t>(); - return range; + gain_range_t get_tx_gain_range(void){ + return _tx_subdev[SUBDEV_PROP_GAIN_RANGE].as<gain_range_t>(); } void set_tx_antenna(const std::string &ant){ diff --git a/host/lib/transport/udp_zero_copy_none.cpp b/host/lib/transport/udp_zero_copy_asio.cpp index 219ae8720..219ae8720 100644 --- a/host/lib/transport/udp_zero_copy_none.cpp +++ b/host/lib/transport/udp_zero_copy_asio.cpp diff --git a/host/lib/types.cpp b/host/lib/types.cpp new file mode 100644 index 000000000..f8a9a9b36 --- /dev/null +++ b/host/lib/types.cpp @@ -0,0 +1,57 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include <uhd/types.hpp> + +using namespace uhd; + +/*********************************************************************** + * gain range + **********************************************************************/ +gain_range_t::gain_range_t(float min_, float max_, float step_){ + min = min_; + max = max_; + step = step_; +} + +/*********************************************************************** + * freq range + **********************************************************************/ +freq_range_t::freq_range_t(double min_, double max_){ + min = min_; + max = max_; +} + +/*********************************************************************** + * tune result + **********************************************************************/ +tune_result_t::tune_result_t(void){ + target_inter_freq = 0.0; + actual_inter_freq = 0.0; + target_dxc_freq = 0.0; + actual_dxc_freq = 0.0; + spectrum_inverted = false; +} + +/*********************************************************************** + * clock config + **********************************************************************/ +clock_config_t::clock_config_t(void){ + ref_source = ""; //not a valid setting + pps_source = ""; //not a valid setting + pps_polarity = POLARITY_NEG; +} diff --git a/host/lib/usrp/dboard/basic.cpp b/host/lib/usrp/dboard/basic.cpp index 02b391244..82485ae6a 100644 --- a/host/lib/usrp/dboard/basic.cpp +++ b/host/lib/usrp/dboard/basic.cpp @@ -17,6 +17,7 @@ #include <uhd/utils.hpp> #include <uhd/props.hpp> +#include <uhd/types.hpp> #include <uhd/usrp/dboard_base.hpp> #include <uhd/usrp/dboard_manager.hpp> #include <boost/assign/list_of.hpp> diff --git a/host/lib/usrp/usrp2/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp index 60622ca47..66e02d469 100644 --- a/host/lib/usrp/usrp2/dboard_impl.cpp +++ b/host/lib/usrp/usrp2/dboard_impl.cpp @@ -45,11 +45,11 @@ void usrp2_impl::dboard_init(void){ ); //load dboards - _rx_dboards[""] = wax_obj_proxy( + _rx_dboards[""] = wax_obj_proxy::make( boost::bind(&usrp2_impl::rx_dboard_get, this, _1, _2), boost::bind(&usrp2_impl::rx_dboard_set, this, _1, _2) ); - _tx_dboards[""] = wax_obj_proxy( + _tx_dboards[""] = wax_obj_proxy::make( boost::bind(&usrp2_impl::tx_dboard_get, this, _1, _2), boost::bind(&usrp2_impl::tx_dboard_set, this, _1, _2) ); diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp index 54ed45e41..34cce0afb 100644 --- a/host/lib/usrp/usrp2/dsp_impl.cpp +++ b/host/lib/usrp/usrp2/dsp_impl.cpp @@ -53,7 +53,7 @@ static boost::uint32_t calculate_iq_scale_word(boost::int16_t i, boost::int16_t void usrp2_impl::init_ddc_config(void){ //create the ddc in the rx dsp dict - _rx_dsps["ddc0"] = wax_obj_proxy( + _rx_dsps["ddc0"] = wax_obj_proxy::make( boost::bind(&usrp2_impl::ddc_get, this, _1, _2), boost::bind(&usrp2_impl::ddc_set, this, _1, _2) ); @@ -201,7 +201,7 @@ void usrp2_impl::ddc_set(const wax::obj &key, const wax::obj &val){ **********************************************************************/ void usrp2_impl::init_duc_config(void){ //create the duc in the tx dsp dict - _tx_dsps["duc0"] = wax_obj_proxy( + _tx_dsps["duc0"] = wax_obj_proxy::make( boost::bind(&usrp2_impl::duc_get, this, _1, _2), boost::bind(&usrp2_impl::duc_set, this, _1, _2) ); diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 4b15c7f3e..cbca8eec7 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -16,7 +16,6 @@ // #include <uhd/utils.hpp> -#include <boost/assign/list_of.hpp> #include "usrp2_impl.hpp" using namespace uhd; @@ -25,7 +24,7 @@ using namespace uhd; * Helper Methods **********************************************************************/ void usrp2_impl::mboard_init(void){ - _mboards[""] = wax_obj_proxy( + _mboards[""] = wax_obj_proxy::make( boost::bind(&usrp2_impl::mboard_get, this, _1, _2), boost::bind(&usrp2_impl::mboard_set, this, _1, _2) ); @@ -36,21 +35,27 @@ void usrp2_impl::mboard_init(void){ } void usrp2_impl::init_clock_config(void){ + //init the ref source clock config + _ref_source_dict = boost::assign::map_list_of + ("int", USRP2_REF_SOURCE_INT) + ("sma", USRP2_REF_SOURCE_SMA) + ("mimo", USRP2_REF_SOURCE_MIMO) + ; + _clock_config.ref_source = "int"; + //init the pps source clock config - _pps_source_dict["sma"] = USRP2_PPS_SOURCE_SMA; - _pps_source_dict["mimo"] = USRP2_PPS_SOURCE_MIMO; - _pps_source = "sma"; + _pps_source_dict = boost::assign::map_list_of + ("sma", USRP2_PPS_SOURCE_SMA) + ("mimo", USRP2_PPS_SOURCE_MIMO) + ; + _clock_config.pps_source = "sma"; //init the pps polarity clock config - _pps_polarity_dict["pos"] = USRP2_PPS_POLARITY_POS; - _pps_polarity_dict["neg"] = USRP2_PPS_POLARITY_NEG; - _pps_polarity = "neg"; - - //init the ref source clock config - _ref_source_dict["int"] = USRP2_REF_SOURCE_INT; - _ref_source_dict["sma"] = USRP2_REF_SOURCE_SMA; - _ref_source_dict["mimo"] = USRP2_REF_SOURCE_MIMO; - _ref_source = "int"; + _pps_polarity_dict = boost::assign::map_list_of + (clock_config_t::POLARITY_POS, USRP2_PPS_POLARITY_POS) + (clock_config_t::POLARITY_NEG, USRP2_PPS_POLARITY_NEG) + ; + _clock_config.pps_polarity = clock_config_t::POLARITY_NEG; //update the clock config (sends a control packet) update_clock_config(); @@ -60,9 +65,9 @@ void usrp2_impl::update_clock_config(void){ //setup the out data usrp2_ctrl_data_t out_data; out_data.id = htonl(USRP2_CTRL_ID_HERES_A_NEW_CLOCK_CONFIG_BRO); - out_data.data.clock_config.pps_source = _pps_source_dict [_pps_source]; - out_data.data.clock_config.pps_polarity = _pps_polarity_dict[_pps_polarity]; - out_data.data.clock_config.ref_source = _ref_source_dict [_ref_source]; + out_data.data.clock_config.ref_source = _ref_source_dict [_clock_config.ref_source]; + out_data.data.clock_config.pps_source = _pps_source_dict [_clock_config.pps_source]; + out_data.data.clock_config.pps_polarity = _pps_polarity_dict[_clock_config.pps_polarity]; //send and recv usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data); @@ -137,7 +142,7 @@ void usrp2_impl::mboard_get(const wax::obj &key_, wax::obj &val){ case MBOARD_PROP_RX_DBOARD: ASSERT_THROW(_rx_dboards.has_key(name)); - val = _rx_dboards[name].get_link(); + val = _rx_dboards[name]->get_link(); return; case MBOARD_PROP_RX_DBOARD_NAMES: @@ -146,7 +151,7 @@ void usrp2_impl::mboard_get(const wax::obj &key_, wax::obj &val){ case MBOARD_PROP_TX_DBOARD: ASSERT_THROW(_tx_dboards.has_key(name)); - val = _tx_dboards[name].get_link(); + val = _tx_dboards[name]->get_link(); return; case MBOARD_PROP_TX_DBOARD_NAMES: @@ -159,7 +164,7 @@ void usrp2_impl::mboard_get(const wax::obj &key_, wax::obj &val){ case MBOARD_PROP_RX_DSP: ASSERT_THROW(_rx_dsps.has_key(name)); - val = _rx_dsps[name].get_link(); + val = _rx_dsps[name]->get_link(); return; case MBOARD_PROP_RX_DSP_NAMES: @@ -168,29 +173,21 @@ void usrp2_impl::mboard_get(const wax::obj &key_, wax::obj &val){ case MBOARD_PROP_TX_DSP: ASSERT_THROW(_tx_dsps.has_key(name)); - val = _tx_dsps[name].get_link(); + val = _tx_dsps[name]->get_link(); return; case MBOARD_PROP_TX_DSP_NAMES: val = prop_names_t(_tx_dsps.get_keys()); return; - case MBOARD_PROP_PPS_SOURCE: - val = _pps_source; + case MBOARD_PROP_CLOCK_CONFIG: + val = _clock_config; return; case MBOARD_PROP_PPS_SOURCE_NAMES: val = prop_names_t(_pps_source_dict.get_keys()); return; - case MBOARD_PROP_PPS_POLARITY: - val = _pps_polarity; - return; - - case MBOARD_PROP_REF_SOURCE: - val = _ref_source; - return; - case MBOARD_PROP_REF_SOURCE_NAMES: val = prop_names_t(_ref_source_dict.get_keys()); return; @@ -237,26 +234,11 @@ void usrp2_impl::mboard_set(const wax::obj &key, const wax::obj &val){ //handle the get request conditioned on the key switch(key.as<mboard_prop_t>()){ - case MBOARD_PROP_PPS_SOURCE:{ - std::string name = val.as<std::string>(); - assert_has(_pps_source_dict.get_keys(), name, "usrp2 pps source"); - _pps_source = name; //shadow - update_clock_config(); - } - return; - - case MBOARD_PROP_PPS_POLARITY:{ - std::string name = val.as<std::string>(); - assert_has(_pps_polarity_dict.get_keys(), name, "usrp2 pps polarity"); - _pps_polarity = name; //shadow - update_clock_config(); - } - return; - - case MBOARD_PROP_REF_SOURCE:{ - std::string name = val.as<std::string>(); - assert_has(_ref_source_dict.get_keys(), name, "usrp2 reference source"); - _ref_source = name; //shadow + case MBOARD_PROP_CLOCK_CONFIG:{ + clock_config_t clock_config = val.as<clock_config_t>(); + assert_has(_pps_source_dict.get_keys(), clock_config.pps_source, "usrp2 pps source"); + assert_has(_ref_source_dict.get_keys(), clock_config.ref_source, "usrp2 ref source"); + _clock_config = clock_config; //shadow update_clock_config(); } return; diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index e1371a094..85d73e83a 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -193,7 +193,7 @@ void usrp2_impl::get(const wax::obj &key_, wax::obj &val){ case DEVICE_PROP_MBOARD: ASSERT_THROW(_mboards.has_key(name)); - val = _mboards[name].get_link(); + val = _mboards[name]->get_link(); return; case DEVICE_PROP_MBOARD_NAMES: diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 765c523fe..70420fd49 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -15,22 +15,23 @@ // along with this program. If not, see <http://www.gnu.org/licenses/>. // +#ifndef INCLUDED_USRP2_IMPL_HPP +#define INCLUDED_USRP2_IMPL_HPP + #include <uhd/usrp/usrp2.hpp> #include <uhd/dict.hpp> -#include <uhd/props.hpp> +#include <uhd/types.hpp> #include <uhd/time_spec.hpp> #include <boost/thread.hpp> #include <boost/shared_ptr.hpp> #include <boost/function.hpp> +#include <boost/assign/list_of.hpp> #include <uhd/transport/vrt.hpp> #include <uhd/transport/udp_simple.hpp> #include <uhd/transport/udp_zero_copy.hpp> #include <uhd/usrp/dboard_manager.hpp> #include "fw_common.h" -#ifndef INCLUDED_USRP2_IMPL_HPP -#define INCLUDED_USRP2_IMPL_HPP - class usrp2_impl; //dummy class declaration /*! @@ -50,20 +51,25 @@ class wax_obj_proxy : public wax::obj{ public: typedef boost::function<void(const wax::obj &, wax::obj &)> get_t; typedef boost::function<void(const wax::obj &, const wax::obj &)> set_t; + typedef boost::shared_ptr<wax_obj_proxy> sptr; + + static sptr make(const get_t &get, const set_t &set){ + return sptr(new wax_obj_proxy(get, set)); + } - wax_obj_proxy(void){ + ~wax_obj_proxy(void){ /* NOP */ } +private: + get_t _get; + set_t _set; + wax_obj_proxy(const get_t &get, const set_t &set){ _get = get; _set = set; }; - ~wax_obj_proxy(void){ - /* NOP */ - } - void get(const wax::obj &key, wax::obj &val){ return _get(key, val); } @@ -71,10 +77,6 @@ public: void set(const wax::obj &key, const wax::obj &val){ return _set(key, val); } - -private: - get_t _get; - set_t _set; }; /*! @@ -98,10 +100,6 @@ public: ~usrp2_impl(void); - //properties interface - void get(const wax::obj &, wax::obj &); - void set(const wax::obj &, const wax::obj &); - //performs a control transaction usrp2_ctrl_data_t ctrl_send_and_recv(const usrp2_ctrl_data_t &); @@ -113,6 +111,10 @@ public: size_t recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const std::string &); private: + //device properties interface + void get(const wax::obj &, wax::obj &); + void set(const wax::obj &, const wax::obj &); + //the raw io interface (samples are in the usrp2 native format) void recv_raw(uhd::rx_metadata_t &); uhd::dict<boost::uint32_t, size_t> _tx_stream_id_to_packet_seq; @@ -141,15 +143,15 @@ private: boost::mutex _ctrl_mutex; //methods and shadows for clock configuration - std::string _pps_source, _pps_polarity, _ref_source; + uhd::clock_config_t _clock_config; void init_clock_config(void); void update_clock_config(void); void set_time_spec(const uhd::time_spec_t &time_spec, bool now); //mappings from clock config strings to over the wire enums - uhd::dict<std::string, usrp2_pps_source_t> _pps_source_dict; - uhd::dict<std::string, usrp2_pps_polarity_t> _pps_polarity_dict; - uhd::dict<std::string, usrp2_ref_source_t> _ref_source_dict; + uhd::dict<std::string, usrp2_ref_source_t> _ref_source_dict; + uhd::dict<std::string, usrp2_pps_source_t> _pps_source_dict; + uhd::dict<uhd::clock_config_t::polarity_t, usrp2_pps_polarity_t> _pps_polarity_dict; //rx and tx dboard methods and objects uhd::usrp::dboard_manager::sptr _dboard_manager; @@ -159,18 +161,18 @@ private: void mboard_init(void); void mboard_get(const wax::obj &, wax::obj &); void mboard_set(const wax::obj &, const wax::obj &); - uhd::dict<std::string, wax_obj_proxy> _mboards; + uhd::dict<std::string, wax_obj_proxy::sptr> _mboards; //properties interface for rx dboard void rx_dboard_get(const wax::obj &, wax::obj &); void rx_dboard_set(const wax::obj &, const wax::obj &); - uhd::dict<std::string, wax_obj_proxy> _rx_dboards; + uhd::dict<std::string, wax_obj_proxy::sptr> _rx_dboards; uhd::prop_names_t _rx_subdevs_in_use; //properties interface for tx dboard void tx_dboard_get(const wax::obj &, wax::obj &); void tx_dboard_set(const wax::obj &, const wax::obj &); - uhd::dict<std::string, wax_obj_proxy> _tx_dboards; + uhd::dict<std::string, wax_obj_proxy::sptr> _tx_dboards; uhd::prop_names_t _tx_subdevs_in_use; void update_mux_config(void); @@ -193,12 +195,12 @@ private: //properties interface for ddc void ddc_get(const wax::obj &, wax::obj &); void ddc_set(const wax::obj &, const wax::obj &); - uhd::dict<std::string, wax_obj_proxy> _rx_dsps; + uhd::dict<std::string, wax_obj_proxy::sptr> _rx_dsps; //properties interface for duc void duc_get(const wax::obj &, wax::obj &); void duc_set(const wax::obj &, const wax::obj &); - uhd::dict<std::string, wax_obj_proxy> _tx_dsps; + uhd::dict<std::string, wax_obj_proxy::sptr> _tx_dsps; }; diff --git a/host/test/CMakeLists.txt b/host/test/CMakeLists.txt index b1d5924c7..1791d9082 100644 --- a/host/test/CMakeLists.txt +++ b/host/test/CMakeLists.txt @@ -15,7 +15,9 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # - +######################################################################## +# unit test suite +######################################################################## ADD_EXECUTABLE(main_test main_test.cpp addr_test.cpp @@ -23,7 +25,10 @@ ADD_EXECUTABLE(main_test vrt_test.cpp wax_test.cpp ) - TARGET_LINK_LIBRARIES(main_test uhd) - ADD_TEST(test main_test) + +######################################################################## +# demo of a loadable module +######################################################################## +ADD_LIBRARY(module_test MODULE module_test.cpp) diff --git a/host/test/gain_handler_test.cpp b/host/test/gain_handler_test.cpp index a4005c0de..47acb30f0 100644 --- a/host/test/gain_handler_test.cpp +++ b/host/test/gain_handler_test.cpp @@ -17,6 +17,7 @@ #include <boost/test/unit_test.hpp> #include <uhd/gain_handler.hpp> +#include <uhd/types.hpp> #include <uhd/props.hpp> #include <uhd/dict.hpp> #include <boost/bind.hpp> @@ -108,12 +109,10 @@ BOOST_AUTO_TEST_CASE(test_gain_handler){ ); std::cout << "verifying the overall min, max, step" << std::endl; - gain_t gain_min, gain_max, gain_step; - boost::tie(gain_min, gain_max, gain_step) = \ - go0[PROP_GAIN_RANGE].as<gain_range_t>(); - BOOST_CHECK_EQUAL(gain_min, gain_t(-10)); - BOOST_CHECK_EQUAL(gain_max, gain_t(100)); - BOOST_CHECK_EQUAL(gain_step, gain_t(1.5)); + gain_range_t gain = go0[PROP_GAIN_RANGE].as<gain_range_t>(); + BOOST_CHECK_EQUAL(gain.min, gain_t(-10)); + BOOST_CHECK_EQUAL(gain.max, gain_t(100)); + BOOST_CHECK_EQUAL(gain.step, gain_t(1.5)); std::cout << "verifying the overall gain" << std::endl; go0[named_prop_t(PROP_GAIN_VALUE, "g0")] = gain_t(-5); diff --git a/host/test/module_test.cpp b/host/test/module_test.cpp new file mode 100644 index 000000000..71721ef90 --- /dev/null +++ b/host/test/module_test.cpp @@ -0,0 +1,26 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include <uhd/utils.hpp> +#include <iostream> + +STATIC_BLOCK(module_test){ + std::cout << "---------------------------------------" << std::endl; + std::cout << "-- Good news, everyone!" << std::endl; + std::cout << "-- The test module has been loaded." << std::endl; + std::cout << "---------------------------------------" << std::endl; +} |