diff options
author | Josh Blum <josh@joshknows.com> | 2011-10-03 18:11:21 -0700 |
---|---|---|
committer | Josh Blum <josh@joshknows.com> | 2011-11-03 20:37:10 -0700 |
commit | 6c13ef7855dcfe9c825e819f69f219851387da25 (patch) | |
tree | 104b646f6fadf7faca92bbd09a2106e8743ad095 | |
parent | 839b9379d436adc1a6b0f876d0d03f11e41dbee6 (diff) | |
download | uhd-6c13ef7855dcfe9c825e819f69f219851387da25.tar.gz uhd-6c13ef7855dcfe9c825e819f69f219851387da25.tar.bz2 uhd-6c13ef7855dcfe9c825e819f69f219851387da25.zip |
uhd: created backwards compatible send/recv implementation
-rw-r--r-- | host/include/uhd/CMakeLists.txt | 1 | ||||
-rw-r--r-- | host/include/uhd/device.hpp | 118 | ||||
-rw-r--r-- | host/include/uhd/device_deprecated.ipp | 181 | ||||
-rw-r--r-- | host/include/uhd/streamer.hpp | 14 |
4 files changed, 197 insertions, 117 deletions
diff --git a/host/include/uhd/CMakeLists.txt b/host/include/uhd/CMakeLists.txt index 08483346c..6b277654d 100644 --- a/host/include/uhd/CMakeLists.txt +++ b/host/include/uhd/CMakeLists.txt @@ -26,6 +26,7 @@ INSTALL(FILES convert.hpp deprecated.hpp device.hpp + device_deprecated.ipp exception.hpp property_tree.ipp property_tree.hpp diff --git a/host/include/uhd/device.hpp b/host/include/uhd/device.hpp index 0ea5259b5..47afe7dc6 100644 --- a/host/include/uhd/device.hpp +++ b/host/include/uhd/device.hpp @@ -19,10 +19,9 @@ #define INCLUDED_UHD_DEVICE_HPP #include <uhd/config.hpp> +#include <uhd/streamer.hpp> #include <uhd/deprecated.hpp> #include <uhd/types/device_addr.hpp> -#include <uhd/types/metadata.hpp> -#include <uhd/types/ref_vector.hpp> #include <boost/utility.hpp> #include <boost/shared_ptr.hpp> #include <boost/function.hpp> @@ -77,116 +76,11 @@ public: */ static sptr make(const device_addr_t &hint, size_t which = 0); - /*! - * Send modes for the device send routine. - */ - enum send_mode_t{ - //! Tells the send routine to send the entire buffer - SEND_MODE_FULL_BUFF = 0, - //! Tells the send routine to return after one packet - SEND_MODE_ONE_PACKET = 1 - }; - - /*! - * Recv modes for the device recv routine. - */ - enum recv_mode_t{ - //! Tells the recv routine to recv the entire buffer - RECV_MODE_FULL_BUFF = 0, - //! Tells the recv routine to return after one packet - RECV_MODE_ONE_PACKET = 1 - }; - - //! Typedef for a pointer to a single, or a collection of send buffers - typedef ref_vector<const void *> send_buffs_type; - - //! Typedef for a pointer to a single, or a collection of recv buffers - typedef ref_vector<void *> recv_buffs_type; - - /*! - * Send buffers containing IF data described by the metadata. - * - * Send handles fragmentation as follows: - * If the buffer has more samples than the maximum per packet, - * the send method will fragment the samples across several packets. - * Send will respect the burst flags when fragmenting to ensure - * that start of burst can only be set on the first fragment and - * that end of burst can only be set on the final fragment. - * Fragmentation only applies in the full buffer send mode. - * - * This is a blocking call and will not return until the number - * of samples returned have been read out of each buffer. - * Under a timeout condition, the number of samples returned - * may be less than the number of samples specified. - * - * \param buffs a vector of read-only memory containing IF data - * \param nsamps_per_buff the number of samples to send, per buffer - * \param metadata data describing the buffer's contents - * \param io_type the type of data loaded in the buffer - * \param send_mode tells send how to unload the buffer - * \param timeout the timeout in seconds to wait on a packet - * \return the number of samples sent - */ - virtual size_t send( - const send_buffs_type &buffs, - size_t nsamps_per_buff, - const tx_metadata_t &metadata, - const io_type_t &io_type, - send_mode_t send_mode, - double timeout = 0.1 - ) = 0; + //! Make a new receive streamer given the list of channels + virtual recv_streamer::sptr get_recv_streamer(const std::vector<size_t> &channels) = 0; - /*! - * Receive buffers containing IF data described by the metadata. - * - * Receive handles fragmentation as follows: - * If the buffer has insufficient space to hold all samples - * that were received in a single packet over-the-wire, - * then the buffer will be completely filled and the implementation - * will hold a pointer into the remaining portion of the packet. - * Subsequent calls will load from the remainder of the packet, - * and will flag the metadata to show that this is a fragment. - * The next call to receive, after the remainder becomes exahausted, - * will perform an over-the-wire receive as usual. - * See the rx metadata fragment flags and offset fields for details. - * - * This is a blocking call and will not return until the number - * of samples returned have been written into each buffer. - * Under a timeout condition, the number of samples returned - * may be less than the number of samples specified. - * - * When using the full buffer recv mode, the metadata only applies - * to the first packet received and written into the recv buffers. - * Use the one packet recv mode to get per packet metadata. - * - * \param buffs a vector of writable memory to fill with IF data - * \param nsamps_per_buff the size of each buffer in number of samples - * \param metadata data to fill describing the buffer - * \param io_type the type of data to fill into the buffer - * \param recv_mode tells recv how to load the buffer - * \param timeout the timeout in seconds to wait for a packet - * \return the number of samples received or 0 on error - */ - virtual size_t recv( - const recv_buffs_type &buffs, - size_t nsamps_per_buff, - rx_metadata_t &metadata, - const io_type_t &io_type, - recv_mode_t recv_mode, - double timeout = 0.1 - ) = 0; - - /*! - * Get the maximum number of samples per packet on send. - * \return the number of samples - */ - virtual size_t get_max_send_samps_per_packet(void) const = 0; - - /*! - * Get the maximum number of samples per packet on recv. - * \return the number of samples - */ - virtual size_t get_max_recv_samps_per_packet(void) const = 0; + //! Make a new transmit streamer given the list of channels + virtual send_streamer::sptr get_send_streamer(const std::vector<size_t> &channels) = 0; /*! * Receive and asynchronous message from the device. @@ -201,6 +95,8 @@ public: //! Get access to the underlying property structure virtual boost::shared_ptr<property_tree> get_tree(void) const = 0; + #include <uhd/device_deprecated.ipp> + }; } //namespace uhd diff --git a/host/include/uhd/device_deprecated.ipp b/host/include/uhd/device_deprecated.ipp new file mode 100644 index 000000000..4b8ec0037 --- /dev/null +++ b/host/include/uhd/device_deprecated.ipp @@ -0,0 +1,181 @@ +// +// Copyright 2010-2011 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/>. +// + +//this file is included inside device class +//it supports the old send/recv functions +//this was replaced by the streamer API + +/*! + * Send modes for the device send routine. + */ +enum send_mode_t{ + //! Tells the send routine to send the entire buffer + SEND_MODE_FULL_BUFF = 0, + //! Tells the send routine to return after one packet + SEND_MODE_ONE_PACKET = 1 +}; + +/*! + * Recv modes for the device recv routine. + */ +enum recv_mode_t{ + //! Tells the recv routine to recv the entire buffer + RECV_MODE_FULL_BUFF = 0, + //! Tells the recv routine to return after one packet + RECV_MODE_ONE_PACKET = 1 +}; + +//! Typedef for a pointer to a single, or a collection of send buffers +typedef ref_vector<const void *> send_buffs_type; + +//! Typedef for a pointer to a single, or a collection of recv buffers +typedef ref_vector<void *> recv_buffs_type; + +/*! + * Send buffers containing IF data described by the metadata. + * + * Send handles fragmentation as follows: + * If the buffer has more samples than the maximum per packet, + * the send method will fragment the samples across several packets. + * Send will respect the burst flags when fragmenting to ensure + * that start of burst can only be set on the first fragment and + * that end of burst can only be set on the final fragment. + * Fragmentation only applies in the full buffer send mode. + * + * This is a blocking call and will not return until the number + * of samples returned have been read out of each buffer. + * Under a timeout condition, the number of samples returned + * may be less than the number of samples specified. + * + * \param buffs a vector of read-only memory containing IF data + * \param nsamps_per_buff the number of samples to send, per buffer + * \param metadata data describing the buffer's contents + * \param io_type the type of data loaded in the buffer + * \param send_mode tells send how to unload the buffer + * \param timeout the timeout in seconds to wait on a packet + * \return the number of samples sent + */ +size_t send( + const send_buffs_type &buffs, + size_t nsamps_per_buff, + const tx_metadata_t &metadata, + const io_type_t &io_type, + send_mode_t send_mode, + double timeout = 0.1 +){ + if (_send_streamer.get() == NULL or _send_streamer->get_num_channels() != buffs.size()){ + std::vector<size_t> chans(buffs.size()); + for (size_t ch = 0; ch < chans.size(); ch++) chans[ch] = ch; + _send_streamer.reset(); //cleanup possible old one + _send_streamer = get_send_streamer(chans); + _send_tid = io_type_t::CUSTOM_TYPE; + } + if (io_type.tid != _send_tid){ + _send_tid = io_type.tid; + _send_streamer->set_format((_send_tid == io_type_t::COMPLEX_FLOAT32)? "fc32" : "sc16", "sc16"); + } + const size_t nsamps = (send_mode == SEND_MODE_ONE_PACKET)? + std::min(nsamps_per_buff, get_max_send_samps_per_packet()) : + nsamps_per_buff; + return _send_streamer->send(buffs, nsamps, metadata, timeout); +} + +/*! + * Receive buffers containing IF data described by the metadata. + * + * Receive handles fragmentation as follows: + * If the buffer has insufficient space to hold all samples + * that were received in a single packet over-the-wire, + * then the buffer will be completely filled and the implementation + * will hold a pointer into the remaining portion of the packet. + * Subsequent calls will load from the remainder of the packet, + * and will flag the metadata to show that this is a fragment. + * The next call to receive, after the remainder becomes exahausted, + * will perform an over-the-wire receive as usual. + * See the rx metadata fragment flags and offset fields for details. + * + * This is a blocking call and will not return until the number + * of samples returned have been written into each buffer. + * Under a timeout condition, the number of samples returned + * may be less than the number of samples specified. + * + * When using the full buffer recv mode, the metadata only applies + * to the first packet received and written into the recv buffers. + * Use the one packet recv mode to get per packet metadata. + * + * \param buffs a vector of writable memory to fill with IF data + * \param nsamps_per_buff the size of each buffer in number of samples + * \param metadata data to fill describing the buffer + * \param io_type the type of data to fill into the buffer + * \param recv_mode tells recv how to load the buffer + * \param timeout the timeout in seconds to wait for a packet + * \return the number of samples received or 0 on error + */ +size_t recv( + const recv_buffs_type &buffs, + size_t nsamps_per_buff, + rx_metadata_t &metadata, + const io_type_t &io_type, + recv_mode_t recv_mode, + double timeout = 0.1 +){ + if (_recv_streamer.get() == NULL or _recv_streamer->get_num_channels() != buffs.size()){ + std::vector<size_t> chans(buffs.size()); + for (size_t ch = 0; ch < chans.size(); ch++) chans[ch] = ch; + _recv_streamer.reset(); //cleanup possible old one + _recv_streamer = get_recv_streamer(chans); + _recv_tid = io_type_t::CUSTOM_TYPE; + } + if (io_type.tid != _recv_tid){ + _recv_tid = io_type.tid; + _recv_streamer->set_format((_recv_tid == io_type_t::COMPLEX_FLOAT32)? "fc32" : "sc16", "sc16"); + } + const size_t nsamps = (recv_mode == RECV_MODE_ONE_PACKET)? + std::min(nsamps_per_buff, get_max_recv_samps_per_packet()) : + nsamps_per_buff; + return _recv_streamer->recv(buffs, nsamps, metadata, timeout); +} + +/*! + * Get the maximum number of samples per packet on send. + * \return the number of samples + */ +size_t get_max_send_samps_per_packet(void){ + if (_send_streamer.get() == NULL){ + std::vector<size_t> chans(1, 0); + _send_streamer = get_send_streamer(chans); + } + return _send_streamer->get_items_per_packet(); +} + +/*! + * Get the maximum number of samples per packet on recv. + * \return the number of samples + */ +size_t get_max_recv_samps_per_packet(void){ + if (_recv_streamer.get() == NULL){ + std::vector<size_t> chans(1, 0); + _recv_streamer = get_recv_streamer(chans); + } + return _recv_streamer->get_items_per_packet(); +} + +private: + recv_streamer::sptr _recv_streamer; + io_type_t::tid_t _recv_tid; + send_streamer::sptr _send_streamer; + io_type_t::tid_t _send_tid; diff --git a/host/include/uhd/streamer.hpp b/host/include/uhd/streamer.hpp index eed18e773..dfbe15ec3 100644 --- a/host/include/uhd/streamer.hpp +++ b/host/include/uhd/streamer.hpp @@ -19,6 +19,8 @@ #define INCLUDED_UHD_STREAMER_HPP #include <uhd/config.hpp> +#include <uhd/types/metadata.hpp> +#include <uhd/types/ref_vector.hpp> #include <boost/utility.hpp> #include <boost/shared_ptr.hpp> #include <string> @@ -87,10 +89,10 @@ public: }; -//! A RX streamer to receive host samples -class UHD_API rx_streamer : public streamer{ +//! A receive streamer to receive host samples +class UHD_API recv_streamer : public streamer{ public: - typedef boost::shared_ptr<rx_streamer> sptr; + typedef boost::shared_ptr<recv_streamer> sptr; //! Typedef for a pointer to a single, or a collection of recv buffers typedef ref_vector<void *> recv_buffs_type; @@ -128,10 +130,10 @@ public: ) = 0; }; -//! A TX streamer to transmit host samples -class UHD_API rx_streamer : public streamer{ +//! A transmit streamer to send host samples +class UHD_API send_streamer : public streamer{ public: - typedef boost::shared_ptr<tx_streamer> sptr; + typedef boost::shared_ptr<send_streamer> sptr; //! Typedef for a pointer to a single, or a collection of send buffers typedef ref_vector<const void *> send_buffs_type; |