diff options
Diffstat (limited to 'host/include')
25 files changed, 1796 insertions, 0 deletions
diff --git a/host/include/CMakeLists.txt b/host/include/CMakeLists.txt new file mode 100644 index 000000000..34b705cab --- /dev/null +++ b/host/include/CMakeLists.txt @@ -0,0 +1,24 @@ +# +# Copyright 2010 Ettus Research LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + + +ADD_SUBDIRECTORY(uhd) + +INSTALL(FILES + uhd.hpp + DESTINATION ${HEADER_DIR} +) diff --git a/host/include/uhd.hpp b/host/include/uhd.hpp new file mode 100644 index 000000000..ee8c13dfe --- /dev/null +++ b/host/include/uhd.hpp @@ -0,0 +1,24 @@ +// +// 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 new file mode 100644 index 000000000..006c54f22 --- /dev/null +++ b/host/include/uhd/CMakeLists.txt @@ -0,0 +1,33 @@ +# +# Copyright 2010 Ettus Research LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + + +ADD_SUBDIRECTORY(transport) +ADD_SUBDIRECTORY(usrp) + +INSTALL(FILES + device.hpp + device_addr.hpp + dict.hpp + gain_handler.hpp + props.hpp + shared_iovec.hpp + time_spec.hpp + utils.hpp + wax.hpp + DESTINATION ${HEADER_DIR}/uhd +) diff --git a/host/include/uhd/device.hpp b/host/include/uhd/device.hpp new file mode 100644 index 000000000..dfbfbd7c0 --- /dev/null +++ b/host/include/uhd/device.hpp @@ -0,0 +1,82 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_DEVICE_HPP +#define INCLUDED_UHD_DEVICE_HPP + +#include <uhd/device_addr.hpp> +#include <uhd/props.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{ + +/*! + * The usrp device interface represents the usrp hardware. + * The api allows for discovery, configuration, and streaming. + */ +class device : boost::noncopyable, public wax::obj{ + +public: + typedef boost::shared_ptr<device> sptr; + + //structors + device(void); + virtual ~device(void); + + /*! + * \brief Discover usrp devices attached to the host. + * + * The hint device address should be used to narrow down the search + * to particular transport types and/or transport arguments. + * + * \param hint a partially (or fully) filled in device address + * \return a vector of device addresses for all usrps on the system + */ + static device_addrs_t discover(const device_addr_t &hint); + + /*! + * \brief Create a new usrp device from the device address hint. + * + * The make routine will call discover and pick one of the results. + * By default, the first result will be used to create a new device. + * Use the which parameter as an index into the list of results. + * + * \param hint a partially (or fully) filled in device address + * \param which which address to use when multiple are discovered + * \return a shared pointer to a new device instance + */ + 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); + + //the io interface + virtual void send_raw(const std::vector<boost::asio::const_buffer> &) = 0; + virtual uhd::shared_iovec recv_raw(void) = 0; +}; + +} //namespace uhd + +#endif /* INCLUDED_UHD_DEVICE_HPP */ diff --git a/host/include/uhd/device_addr.hpp b/host/include/uhd/device_addr.hpp new file mode 100644 index 000000000..8ea580321 --- /dev/null +++ b/host/include/uhd/device_addr.hpp @@ -0,0 +1,67 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_DEVICE_ADDR_HPP +#define INCLUDED_UHD_DEVICE_ADDR_HPP + +#include <uhd/dict.hpp> +#include <string> +#include <iostream> +#include <netinet/ether.h> +#include <stdint.h> +#include <vector> + +namespace uhd{ + + /*! + * Wrapper for an ethernet mac address. + * Provides conversion between string and binary formats. + */ + struct mac_addr_t{ + struct ether_addr mac_addr; + mac_addr_t(const std::string &mac_addr_str = "00:00:00:00:00:00"); + std::string to_string(void) const; + }; + + /*! + * The device address args are just a mapping of key/value string pairs. + * When left empty, the discovery routine will try to find all usrps. + * The discovery can be narrowed down by specifying the transport type arguments. + * + * For example, to access a specific usrp2 one would specify the transport type + * ("type", "udp") and the transport args ("addr", "<resolvable_hostname_or_addr>"). + */ + typedef dict<std::string, std::string> device_addr_t; + typedef std::vector<device_addr_t> device_addrs_t; + + /*! + * Function to turn a device address into a string. + * Just having the operator<< below should be sufficient. + * However, boost format seems to complain with the % + * and this is just easier because it works. + * \param device_addr a device address instance + * \return the string representation + */ + std::string device_addr_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 &); + +#endif /* INCLUDED_UHD_DEVICE_ADDR_HPP */ diff --git a/host/include/uhd/dict.hpp b/host/include/uhd/dict.hpp new file mode 100644 index 000000000..1ed28551a --- /dev/null +++ b/host/include/uhd/dict.hpp @@ -0,0 +1,140 @@ +// +// 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_DICT_HPP +#define INCLUDED_UHD_DICT_HPP + +#include <map> +#include <vector> +#include <stdexcept> +#include <boost/foreach.hpp> + +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; + + /*! + * Create a new empty dictionary. + */ + dict(void){ + /* NOP */ + } + + /*! + * Create a dictionary from a map. + * \param map a map with key value pairs + */ + dict(const map_t &map){ + _map = map; + } + + /*! + * Destroy this dict. + */ + ~dict(void){ + /* NOP */ + } + + /*! + * Get a list of the keys in this dict. + * \return vector of keys + */ + std::vector<Key> get_keys(void) const{ + std::vector<Key> keys; + BOOST_FOREACH(pair_t p, _map){ + keys.push_back(p.first); + } + return keys; + } + + /*! + * Get a list of the values in this dict. + * \return vector of values + */ + std::vector<Val> get_vals(void) const{ + std::vector<Val> vals; + BOOST_FOREACH(pair_t p, _map){ + vals.push_back(p.second); + } + return vals; + } + + /*! + * Does the dictionary contain this key? + * \param key the key to look for + * \return true if found + */ + bool has_key(const Key &key) const{ + BOOST_FOREACH(pair_t p, _map){ + if (p.first == key) return true; + } + return false; + } + + /*! + * Get a value for the given key if it exists. + * If the key is not found throw an error. + * \param key the key to look for + * \return the value at the key + * \throw an exception when not found + */ + const Val &operator[](const Key &key) const{ + if (has_key(key)){ + return _map.find(key)->second; + } + throw std::invalid_argument("key not found in dict"); + } + + /*! + * Set a value for the given key, however, in reality + * it really returns a reference which can be assigned to. + * \param key the key to set to + * \return a reference to the value + */ + Val &operator[](const Key &key){ + return _map[key]; + } + + /*! + * Pop an item out of the dictionary. + * \param key the item key + * \return the value of the item + * \throw an exception when not found + */ + Val pop_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"); + } + + private: + map_t _map; //private container + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_DICT_HPP */ diff --git a/host/include/uhd/gain_handler.hpp b/host/include/uhd/gain_handler.hpp new file mode 100644 index 000000000..06800315a --- /dev/null +++ b/host/include/uhd/gain_handler.hpp @@ -0,0 +1,101 @@ +// +// 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/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 + +namespace uhd{ + +class gain_handler{ +public: + typedef boost::shared_ptr<gain_handler> sptr; + + 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); + } + + ~gain_handler(void); + + /*! + * 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); + + /*! + * Intercept sets for overall gain. + * Ensures that the gain name is valid. + * 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; + + /*! + * 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: + * 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); + } + catch(const wax::bad_cast &){ + return false; + } + } + boost::function<bool(const wax::obj &, const wax::obj &)> _is_equal; + +}; + +} //namespace uhd + +#endif /* INCLUDED_UHD_GAIN_HANDLER_HPP */ + diff --git a/host/include/uhd/props.hpp b/host/include/uhd/props.hpp new file mode 100644 index 000000000..4012ffbd2 --- /dev/null +++ b/host/include/uhd/props.hpp @@ -0,0 +1,165 @@ +// +// 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/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 + typedef int int_scalar_t; + typedef float real_scalar_t; + typedef std::complex<real_scalar_t> complex_scalar_t; + + //vector types + 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; + + //typedef for handling named properties + typedef std::vector<std::string> prop_names_t; + typedef boost::tuple<wax::obj, std::string> named_prop_t; + + /*! + * Utility function to separate a named property into its components. + * \param key a reference to the prop object + * \param name a reference to the name object + */ + inline named_prop_t 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 named_prop_t(key, name); + } + + /*! + * Possible device properties: + * In general, a device will have a single mboard. + * In certain mimo applications, multiple boards + * will be present in the interface for configuration. + */ + enum device_prop_t{ + DEVICE_PROP_NAME, //ro, std::string + DEVICE_PROP_MBOARD, //ro, wax::obj + DEVICE_PROP_MBOARD_NAMES //ro, prop_names_t + }; + + /*! + * Possible device mboard properties: + * The general mboard properties are listed below. + * Custom properties can be identified with a string + * and discovered though the others property. + */ + enum mboard_prop_t{ + MBOARD_PROP_NAME, //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 + MBOARD_PROP_TX_DSP, //ro, wax::obj + MBOARD_PROP_TX_DSP_NAMES, //ro, prop_names_t + MBOARD_PROP_RX_DBOARD, //ro, wax::obj + 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_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 + }; + + /*! + * Possible device dsp properties: + * A dsp can have a wide range of possible properties. + * A ddc would have a properties "decim", "freq", "taps"... + * Other properties could be gains, complex scalars, enables... + * For this reason the only required properties of a dsp is a name + * and a property to get list of other possible properties. + */ + enum dsp_prop_t{ + DSP_PROP_NAME, //ro, std::string + DSP_PROP_OTHERS //ro, prop_names_t + }; + + /*! + * Possible device dboard properties + */ + enum dboard_prop_t{ + 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 + }; + + /*! + * Possible device codec properties: + * A codec is expected to have a rate and gain elements. + * Other properties can be discovered through the others prop. + */ + enum codec_prop_t{ + CODEC_PROP_NAME, //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_NAMES, //ro, prop_names_t + CODEC_PROP_CLOCK_RATE //ro, freq_t + }; + + /*! + * Possible device subdev properties + */ + enum subdev_prop_t{ + 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_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_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 + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_PROPS_HPP */ diff --git a/host/include/uhd/shared_iovec.hpp b/host/include/uhd/shared_iovec.hpp new file mode 100644 index 000000000..a120e55d5 --- /dev/null +++ b/host/include/uhd/shared_iovec.hpp @@ -0,0 +1,54 @@ +// +// 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/time_spec.hpp b/host/include/uhd/time_spec.hpp new file mode 100644 index 000000000..e5657e555 --- /dev/null +++ b/host/include/uhd/time_spec.hpp @@ -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 <stdint.h> + +#ifndef INCLUDED_UHD_TIME_SPEC_HPP +#define INCLUDED_UHD_TIME_SPEC_HPP + +namespace uhd{ + + /*! + * A time_spec_t holds a seconds and ticks time value. + * The temporal width of a tick depends on the device's clock rate. + * 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; + + /*! + * Create a time_spec_t that holds a wildcard time. + * This will have implementation-specific meaning. + */ + time_spec_t(void){ + secs = ~0; + ticks = ~0; + } + + /*! + * 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; + } + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TIME_SPEC_HPP */ diff --git a/host/include/uhd/transport/CMakeLists.txt b/host/include/uhd/transport/CMakeLists.txt new file mode 100644 index 000000000..b786eb945 --- /dev/null +++ b/host/include/uhd/transport/CMakeLists.txt @@ -0,0 +1,22 @@ +# +# Copyright 2010 Ettus Research LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + + +INSTALL(FILES + udp.hpp + DESTINATION ${HEADER_DIR}/uhd/transport +) diff --git a/host/include/uhd/transport/udp.hpp b/host/include/uhd/transport/udp.hpp new file mode 100644 index 000000000..6db6bd377 --- /dev/null +++ b/host/include/uhd/transport/udp.hpp @@ -0,0 +1,75 @@ +// +// 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/usrp/CMakeLists.txt b/host/include/uhd/usrp/CMakeLists.txt new file mode 100644 index 000000000..d3040c3cc --- /dev/null +++ b/host/include/uhd/usrp/CMakeLists.txt @@ -0,0 +1,25 @@ +# +# Copyright 2010 Ettus Research LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + + +ADD_SUBDIRECTORY(dboard) +ADD_SUBDIRECTORY(mboard) + +INSTALL(FILES + usrp.hpp + DESTINATION ${HEADER_DIR}/uhd/usrp +) diff --git a/host/include/uhd/usrp/dboard/CMakeLists.txt b/host/include/uhd/usrp/dboard/CMakeLists.txt new file mode 100644 index 000000000..e1ecc3b70 --- /dev/null +++ b/host/include/uhd/usrp/dboard/CMakeLists.txt @@ -0,0 +1,25 @@ +# +# Copyright 2010 Ettus Research LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + + +INSTALL(FILES + base.hpp + id.hpp + interface.hpp + manager.hpp + DESTINATION ${HEADER_DIR}/uhd/usrp/dboard +) diff --git a/host/include/uhd/usrp/dboard/base.hpp b/host/include/uhd/usrp/dboard/base.hpp new file mode 100644 index 000000000..845e2f669 --- /dev/null +++ b/host/include/uhd/usrp/dboard/base.hpp @@ -0,0 +1,111 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_USRP_DBOARD_BASE_HPP +#define INCLUDED_UHD_USRP_DBOARD_BASE_HPP + +#include <uhd/wax.hpp> +#include <boost/utility.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/tuple/tuple.hpp> +#include <uhd/usrp/dboard/interface.hpp> + +namespace uhd{ namespace usrp{ namespace dboard{ + +/*! + * A daughter board base class for all dboards. + * Only other dboard base classes should inherit this. + */ +class base : boost::noncopyable{ +public: + typedef boost::shared_ptr<base> sptr; + //the constructor args consist of a subdev name and an interface + //derived classes should pass the args into the base class ctor + //but should not have to deal with the internals of the args + typedef boost::tuple<std::string, interface::sptr> ctor_args_t; + + //structors + base(ctor_args_t const&); + virtual ~base(void); + + //interface + virtual void rx_get(const wax::obj &key, wax::obj &val) = 0; + virtual void rx_set(const wax::obj &key, const wax::obj &val) = 0; + virtual void tx_get(const wax::obj &key, wax::obj &val) = 0; + virtual void tx_set(const wax::obj &key, const wax::obj &val) = 0; + +protected: + std::string get_subdev_name(void); + interface::sptr get_interface(void); + +private: + std::string _subdev_name; + interface::sptr _dboard_interface; +}; + +/*! + * A xcvr daughter board implements rx and tx methods + * Sub classes for xcvr boards should inherit this. + */ +class xcvr_base : public base{ +public: + /*! + * Create a new xcvr dboard object, override in subclasses. + */ + xcvr_base(ctor_args_t const&); + virtual ~xcvr_base(void); +}; + +/*! + * A rx daughter board only implements rx methods. + * Sub classes for rx-only boards should inherit this. + */ +class rx_base : public base{ +public: + /*! + * Create a new rx dboard object, override in subclasses. + */ + rx_base(ctor_args_t const&); + + virtual ~rx_base(void); + + //override here so the derived classes cannot + void tx_get(const wax::obj &key, wax::obj &val); + void tx_set(const wax::obj &key, const wax::obj &val); +}; + +/*! + * A tx daughter board only implements tx methods. + * Sub classes for rx-only boards should inherit this. + */ +class tx_base : public base{ +public: + /*! + * Create a new rx dboard object, override in subclasses. + */ + tx_base(ctor_args_t const&); + + virtual ~tx_base(void); + + //override here so the derived classes cannot + void rx_get(const wax::obj &key, wax::obj &val); + void rx_set(const wax::obj &key, const wax::obj &val); +}; + +}}} //namespace + +#endif /* INCLUDED_UHD_USRP_DBOARD_BASE_HPP */ diff --git a/host/include/uhd/usrp/dboard/id.hpp b/host/include/uhd/usrp/dboard/id.hpp new file mode 100644 index 000000000..98c0acc3a --- /dev/null +++ b/host/include/uhd/usrp/dboard/id.hpp @@ -0,0 +1,35 @@ +// +// 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 <iostream> + +#ifndef INCLUDED_UHD_USRP_DBOARD_ID_HPP +#define INCLUDED_UHD_USRP_DBOARD_ID_HPP + +namespace uhd{ namespace usrp{ namespace dboard{ + +enum dboard_id_t{ + ID_NONE = 0xffff, + ID_BASIC_TX = 0x0000, + ID_BASIC_RX = 0x0001 +}; + +}}} //namespace + +std::ostream& operator<<(std::ostream &, const uhd::usrp::dboard::dboard_id_t &); + +#endif /* INCLUDED_UHD_USRP_DBOARD_ID_HPP */ diff --git a/host/include/uhd/usrp/dboard/interface.hpp b/host/include/uhd/usrp/dboard/interface.hpp new file mode 100644 index 000000000..68669b99d --- /dev/null +++ b/host/include/uhd/usrp/dboard/interface.hpp @@ -0,0 +1,167 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_USRP_DBOARD_INTERFACE_HPP +#define INCLUDED_UHD_USRP_DBOARD_INTERFACE_HPP + +#include <boost/shared_ptr.hpp> +#include <stdint.h> + +namespace uhd{ namespace usrp{ namespace dboard{ + +/*! + * The daughter board interface to be subclassed. + * A dboard instance interfaces with the mboard though this api. + * This interface provides i2c, spi, gpio, atr, aux dac/adc access. + * Each mboard should have a specially tailored dboard interface. + */ +class interface{ +public: + typedef boost::shared_ptr<interface> sptr; + + //tells the host which device to use + enum spi_dev_t{ + SPI_TX_DEV, + SPI_RX_DEV + }; + + //args for writing spi data + enum spi_push_t{ + SPI_PUSH_RISE, + SPI_PUSH_FALL + }; + + //args for reading spi data + enum spi_latch_t{ + SPI_LATCH_RISE, + SPI_LATCH_FALL + }; + + //tell the host which gpio bank + enum gpio_bank_t{ + GPIO_TX_BANK, + GPIO_RX_BANK + }; + + //structors + interface(void); + virtual ~interface(void); + + /*! + * Write to an aux dac. + * \param which_dac the dac index 0, 1, 2, 3... + * \param value the value to write + */ + virtual void write_aux_dac(int which_dac, int value) = 0; + + /*! + * Read from an aux adc. + * \param which_adc the adc index 0, 1, 2, 3... + * \return the value that was read + */ + virtual int read_aux_adc(int which_adc) = 0; + + /*! + * Set daughterboard ATR register. + * The ATR register for a particular bank has 2 values: + * one value when transmitting, one when receiving. + * The mask controls which pins are controlled by ATR. + * + * \param bank GPIO_TX_BANK or GPIO_RX_BANK + * \param tx_value 16-bits, 0=FPGA output low, 1=FPGA output high + * \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; + + /*! + * Set daughterboard GPIO data direction register. + * + * \param bank GPIO_TX_BANK or GPIO_RX_BANK + * \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; + + /*! + * Set daughterboard GPIO pin values. + * + * \param bank GPIO_TX_BANK or GPIO_RX_BANK + * \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; + + /*! + * Read daughterboard GPIO pin values + * + * \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; + + /*! + * \brief Write to I2C peripheral + * \param i2c_addr I2C bus address (7-bits) + * \param buf the data to write + */ + virtual void write_i2c(int i2c_addr, const std::string &buf) = 0; + + /*! + * \brief Read from I2C peripheral + * \param i2c_addr I2C bus address (7-bits) + * \param len number of bytes to read + * \return the data read if successful, else a zero length string. + */ + virtual std::string read_i2c(int i2c_addr, size_t len) = 0; + + /*! + * \brief Write data to SPI bus peripheral. + * + * \param dev which spi device + * \param push args for writing + * \param buf the data to write + */ + virtual void write_spi(spi_dev_t dev, spi_push_t push, const std::string &buf) = 0; + + /*! + * \brief Read data from SPI bus peripheral. + * + * \param dev which spi device + * \param push args for reading + * \param len number of bytes to read + * \return the data read if sucessful, else a zero length string. + */ + virtual std::string read_spi(spi_dev_t dev, spi_latch_t latch, size_t len) = 0; + + /*! + * \brief Get the rate of the rx dboard clock. + * \return the clock rate + */ + virtual double get_rx_clock_rate(void) = 0; + + /*! + * \brief Get the rate of the tx dboard clock. + * \return the clock rate + */ + virtual double get_tx_clock_rate(void) = 0; + +}; + +}}} //namespace + +#endif /* INCLUDED_UHD_USRP_DBOARD_INTERFACE_HPP */ diff --git a/host/include/uhd/usrp/dboard/manager.hpp b/host/include/uhd/usrp/dboard/manager.hpp new file mode 100644 index 000000000..e53ba8e52 --- /dev/null +++ b/host/include/uhd/usrp/dboard/manager.hpp @@ -0,0 +1,82 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_USRP_DBOARD_MANAGER_HPP +#define INCLUDED_UHD_USRP_DBOARD_MANAGER_HPP + +#include <uhd/dict.hpp> +#include <uhd/wax.hpp> +#include <uhd/props.hpp> +#include <boost/utility.hpp> +#include <boost/shared_ptr.hpp> +#include <uhd/usrp/dboard/base.hpp> +#include <uhd/usrp/dboard/id.hpp> + +namespace uhd{ namespace usrp{ namespace dboard{ + +/*! + * A daughter board subdev manager class. + * Create subdev instances for each subdev on a dboard. + * Provide wax::obj access to the subdevs inside. + */ +class manager : boost::noncopyable{ + +public: + + //dboard constructor (each dboard should have a ::make with this signature) + typedef base::sptr(*dboard_ctor_t)(base::ctor_args_t const&); + + /*! + * Register subdevices for a given dboard id. + * + * \param dboard_id the dboard id (rx or tx) + * \param dboard_ctor the dboard constructor function pointer + * \param subdev_names the names of the subdevs on this dboard + */ + static void register_subdevs( + dboard_id_t dboard_id, + dboard_ctor_t dboard_ctor, + const prop_names_t &subdev_names + ); + +public: + typedef boost::shared_ptr<manager> sptr; + //structors + manager( + dboard_id_t rx_dboard_id, + dboard_id_t tx_dboard_id, + interface::sptr dboard_interface + ); + ~manager(void); + + //interface + prop_names_t get_rx_subdev_names(void); + prop_names_t get_tx_subdev_names(void); + wax::obj get_rx_subdev(const std::string &subdev_name); + wax::obj get_tx_subdev(const std::string &subdev_name); + +private: + //list of rx and tx dboards in this manager + //each dboard here is actually a subdevice proxy + //the subdevice proxy is internal to the cpp file + uhd::dict<std::string, wax::obj> _rx_dboards; + uhd::dict<std::string, wax::obj> _tx_dboards; +}; + +}}} //namespace + +#endif /* INCLUDED_UHD_USRP_DBOARD_MANAGER_HPP */ diff --git a/host/include/uhd/usrp/mboard/CMakeLists.txt b/host/include/uhd/usrp/mboard/CMakeLists.txt new file mode 100644 index 000000000..79aab8677 --- /dev/null +++ b/host/include/uhd/usrp/mboard/CMakeLists.txt @@ -0,0 +1,24 @@ +# +# Copyright 2010 Ettus Research LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + + +INSTALL(FILES + base.hpp + test.hpp + usrp2.hpp + DESTINATION ${HEADER_DIR}/uhd/usrp/mboard +) diff --git a/host/include/uhd/usrp/mboard/base.hpp b/host/include/uhd/usrp/mboard/base.hpp new file mode 100644 index 000000000..a8de81a7e --- /dev/null +++ b/host/include/uhd/usrp/mboard/base.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_USRP_MBOARD_BASE_HPP +#define INCLUDED_UHD_USRP_MBOARD_BASE_HPP + +#include <uhd/wax.hpp> +#include <boost/utility.hpp> +#include <boost/shared_ptr.hpp> + +namespace uhd{ namespace usrp{ namespace mboard{ + +/*! + * A base class for usrp mboard objects. + */ +class base : boost::noncopyable, public wax::obj{ +public: + typedef boost::shared_ptr<base> sptr; + base(void); + ~base(void); + + //TODO other api calls + +private: + virtual void get(const wax::obj &, wax::obj &) = 0; + virtual void set(const wax::obj &, const wax::obj &) = 0; +}; + +}}} //namespace + +#endif /* INCLUDED_UHD_USRP_MBOARD_BASE_HPP */ diff --git a/host/include/uhd/usrp/mboard/test.hpp b/host/include/uhd/usrp/mboard/test.hpp new file mode 100644 index 000000000..04d0ff4c4 --- /dev/null +++ b/host/include/uhd/usrp/mboard/test.hpp @@ -0,0 +1,46 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_USRP_MBOARD_TEST_HPP +#define INCLUDED_UHD_USRP_MBOARD_TEST_HPP + +#include <uhd/usrp/mboard/base.hpp> +#include <uhd/device_addr.hpp> +#include <uhd/usrp/dboard/manager.hpp> +#include <uhd/dict.hpp> + +namespace uhd{ namespace usrp{ namespace mboard{ + +/*! + * A test usrp mboard object. + * Exercises access routines for the test suite. + */ +class test : public base{ +public: + test(const device_addr_t &); + ~test(void); + +private: + void get(const wax::obj &, wax::obj &); + void set(const wax::obj &, const wax::obj &); + + uhd::dict<std::string, dboard::manager::sptr> _dboard_managers; +}; + +}}} //namespace + +#endif /* INCLUDED_UHD_USRP_MBOARD_TEST_HPP */ diff --git a/host/include/uhd/usrp/mboard/usrp2.hpp b/host/include/uhd/usrp/mboard/usrp2.hpp new file mode 100644 index 000000000..5da9f874d --- /dev/null +++ b/host/include/uhd/usrp/mboard/usrp2.hpp @@ -0,0 +1,51 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_USRP_MBOARD_USRP2_HPP +#define INCLUDED_UHD_USRP_MBOARD_USRP2_HPP + +#include <uhd/usrp/mboard/base.hpp> +#include <uhd/device_addr.hpp> + +namespace uhd{ namespace usrp{ namespace mboard{ + +/*! + * The usrp2 mboard class. + */ +class usrp2 : public base{ +public: + /*! + * Discover usrp2 devices over the ethernet. + * 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 + */ + static device_addrs_t discover(const device_addr_t &hint); + + usrp2(const device_addr_t &); + ~usrp2(void); + +private: + void get(const wax::obj &, wax::obj &); + void set(const wax::obj &, const wax::obj &); + + wax::obj _impl; +}; + +}}} //namespace + +#endif /* INCLUDED_UHD_USRP_MBOARD_USRP2_HPP */ diff --git a/host/include/uhd/usrp/usrp.hpp b/host/include/uhd/usrp/usrp.hpp new file mode 100644 index 000000000..98c357b77 --- /dev/null +++ b/host/include/uhd/usrp/usrp.hpp @@ -0,0 +1,53 @@ +// +// 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/device.hpp> +#include <uhd/usrp/mboard/base.hpp> +#include <uhd/dict.hpp> + +#ifndef INCLUDED_UHD_USRP_USRP_HPP +#define INCLUDED_UHD_USRP_USRP_HPP + +namespace uhd{ namespace usrp{ + +/*! + * A usrp device provides a device-level interface to usrp mboards. + * In most cases, a usrp device will have only one mboard. + * In the usrp2 mimo case, this device will have two mboards, + * where one talks through the other's control port. + */ +class usrp : public device{ +public: + usrp(const device_addr_t &device_addr); + ~usrp(void); + + //the io interface + void send_raw(const std::vector<boost::asio::const_buffer> &); + uhd::shared_iovec recv_raw(void); + +private: + void get(const wax::obj &, wax::obj &); + void set(const wax::obj &, const wax::obj &); + + uhd::dict<std::string, mboard::base::sptr> _mboards; + boost::function<void(const std::vector<boost::asio::const_buffer> &)> _send_raw_cb; + boost::function<uhd::shared_iovec(void)> _recv_raw_cb; +}; + +}} //namespace + +#endif /* INCLUDED_UHD_USRP_USRP_HPP */ diff --git a/host/include/uhd/utils.hpp b/host/include/uhd/utils.hpp new file mode 100644 index 000000000..4331aba7e --- /dev/null +++ b/host/include/uhd/utils.hpp @@ -0,0 +1,121 @@ +// +// 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/wax.hpp> +#include <boost/foreach.hpp> +#include <boost/format.hpp> +#include <boost/function.hpp> +#include <stdexcept> +#include <algorithm> +#include <vector> +#include <map> + +#ifndef INCLUDED_UHD_UTILS_HPP +#define INCLUDED_UHD_UTILS_HPP + +/*! + * Useful templated functions and classes that I like to pretend are part of stl + */ +namespace std{ + + class assert_error : public std::logic_error{ + public: + explicit assert_error(const string& what_arg) : logic_error(what_arg){ + /* NOP */ + } + }; + + #define ASSERT_THROW(_x) if (not (_x)) { \ + throw std::assert_error("Assertion Failed: " + std::string(#_x)); \ + } + + template<class T, class InputIterator, class Function> + T reduce(InputIterator first, InputIterator last, Function fcn, T init = 0){ + T tmp = init; + for ( ; first != last; ++first ){ + tmp = fcn(tmp, *first); + } + return tmp; + } + + 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<typename T> T signum(T n){ + if (n < 0) return -1; + if (n > 0) return 1; + return 0; + } + +}//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 + } + + 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*/ + +#endif /* INCLUDED_UHD_UTILS_HPP */ diff --git a/host/include/uhd/wax.hpp b/host/include/uhd/wax.hpp new file mode 100644 index 000000000..1d5054351 --- /dev/null +++ b/host/include/uhd/wax.hpp @@ -0,0 +1,167 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_WAX_HPP +#define INCLUDED_WAX_HPP + +#include <boost/any.hpp> +#include <iostream> + +/*! + * WAX - it's a metaphor! + * + * The WAX framework allows 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. + * + * 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] + * + * 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). + */ + +namespace wax{ + + /*! + * WAX object base class: + * + * A wax obj has two major purposes: + * 1) to act as a polymorphic container, just like boost any + * 2) to provide a nested set/get properties interface + * + * Internally, the polymorphic container is handled by a boost any. + * For properties, a subclass should override the set and get methods. + * For property nesting, wax obj subclasses return special links + * to other wax obj subclasses, and the api handles the magic. + */ + class obj{ + public: + + /*! + * Default constructor: + * The contents will be empty. + */ + obj(void); + + /*! + * Copy constructor: + * The contents will be cloned. + * \param o another wax::obj + */ + obj(const obj &o); + + /*! + * Templated any type constructor: + * The contents can be anything. + * Uses the boost::any to handle the magic. + * \param o an object of any type + */ + template<class T> obj(const T &o){ + _contents = o; + } + + /*! + * Destructor. + */ + virtual ~obj(void); + + /*! + * The chaining operator: + * This operator allows access objs with properties. + * A call to the [] operator will return a new proxy obj. + * The proxy object is an obj with special proxy contents. + * Assignment and casting can be used on this special object + * to access the property referenced by the obj key. + * \param key a key to identify a property within this obj + * \return a special wax obj that proxies the obj and key + */ + obj operator[](const obj &key); + + /*! + * The assignment operator: + * This operator allows for assignment of new contents. + * In the special case where this obj contains a proxy, + * the value will be set to the proxy's property reference. + * \param val the new value to assign to the wax obj + * \return a reference to this obj (*this) + */ + obj & operator=(const obj &val); + + /*! + * Get a link in the chain: + * When a wax obj returns another wax obj as part of a get call, + * the return value should be set to the result of this method. + * Doing so will ensure chain-ability of the returned object. + * \return an obj containing a valid link to a wax obj + */ + obj get_link(void) const; + + /*! + * Get the type of the contents of this obj. + * \return a reference to the type_info + */ + const std::type_info & type(void) const; + + private: + //private interface (override in subclasses) + virtual void get(const obj &, obj &); + virtual void set(const obj &, const obj &); + + /*! + * Resolve the contents of this obj. + * In the case where this obj is a proxy, + * the referenced property will be resolved. + * Otherwise, just get the private contents. + * \return a boost any type with contents + */ + boost::any resolve(void) const; + 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 */ |