diff options
Diffstat (limited to 'host/include')
| -rw-r--r-- | host/include/uhd/transport/nirio/nirio_fifo.h | 6 | ||||
| -rw-r--r-- | host/include/uhd/transport/nirio/nirio_fifo.ipp | 234 | ||||
| -rw-r--r-- | host/include/uhd/transport/nirio/nirio_quirks.h | 4 | ||||
| -rw-r--r-- | host/include/uhd/types/metadata.hpp | 16 | ||||
| -rw-r--r-- | host/include/uhd/usrp/multi_usrp.hpp | 8 | ||||
| -rw-r--r-- | host/include/uhd/utils/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | host/include/uhd/utils/cast.hpp | 43 | 
7 files changed, 208 insertions, 104 deletions
| diff --git a/host/include/uhd/transport/nirio/nirio_fifo.h b/host/include/uhd/transport/nirio/nirio_fifo.h index f7abb396f..fc1de245d 100644 --- a/host/include/uhd/transport/nirio/nirio_fifo.h +++ b/host/include/uhd/transport/nirio/nirio_fifo.h @@ -104,16 +104,20 @@ public:          uint32_t& num_remaining);  private:    //Methods -    bool _is_initialized();      datatype_info_t _get_datatype_info();      nirio_status _get_transfer_count(uint64_t& transfer_count);      nirio_status _ensure_transfer_completed(uint32_t timeout_ms);  private:    //Members +    enum fifo_state_t { +        UNMAPPED, MAPPED, STARTED +    }; +      std::string                    _name;      fifo_direction_t               _fifo_direction;      uint32_t                       _fifo_channel;      datatype_info_t                _datatype_info; +    fifo_state_t                   _state;      size_t                         _acquired_pending;      nirio_driver_iface::rio_mmap_t _mem_map;      boost::recursive_mutex         _mutex; diff --git a/host/include/uhd/transport/nirio/nirio_fifo.ipp b/host/include/uhd/transport/nirio/nirio_fifo.ipp index 80a0c2a89..437e3a1fc 100644 --- a/host/include/uhd/transport/nirio/nirio_fifo.ipp +++ b/host/include/uhd/transport/nirio/nirio_fifo.ipp @@ -31,6 +31,7 @@ nirio_fifo<data_t>::nirio_fifo(      _fifo_direction(direction),      _fifo_channel(fifo_instance),      _datatype_info(_get_datatype_info()), +    _state(UNMAPPED),      _acquired_pending(0),      _mem_map(),      _riok_proxy_ptr(&riok_proxy), @@ -61,28 +62,37 @@ nirio_status nirio_fifo<data_t>::initialize(      if (!_riok_proxy_ptr) return NiRio_Status_ResourceNotInitialized;      boost::unique_lock<boost::recursive_mutex> lock(_mutex); -    nirio_driver_iface::nirio_syncop_in_params_t in = {}; -    nirio_driver_iface::nirio_syncop_out_params_t out = {}; +    if (_state == UNMAPPED) { +        nirio_driver_iface::nirio_syncop_in_params_t in = {}; +        nirio_driver_iface::nirio_syncop_out_params_t out = {}; -    //Forcefully stop the fifo if it is running -    in.function    = nirio_driver_iface::NIRIO_FUNC::FIFO; -    in.subfunction = nirio_driver_iface::NIRIO_FIFO::STOP; -    status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); +        //Forcefully stop the fifo if it is running +        in.function    = nirio_driver_iface::NIRIO_FUNC::FIFO; +        in.subfunction = nirio_driver_iface::NIRIO_FIFO::STOP; +        in.params.fifo.channel = _fifo_channel; +        _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out));    //Cleanup operation. Ignore status. -    in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; -    in.subfunction = nirio_driver_iface::NIRIO_FIFO::CONFIGURE; +        //Configure the FIFO now that we know it is stopped +        in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; +        in.subfunction = nirio_driver_iface::NIRIO_FIFO::CONFIGURE; +        in.params.fifo.channel = _fifo_channel; +        in.params.fifo.op.config.requestedDepth = static_cast<uint32_t>(requested_depth); +        in.params.fifo.op.config.requiresActuals = 1; +        status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); -    in.params.fifo.channel = _fifo_channel; -    in.params.fifo.op.config.requestedDepth = static_cast<uint32_t>(requested_depth); -    in.params.fifo.op.config.requiresActuals = 1; +        if (nirio_status_fatal(status)) return status; -    status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); -    if (nirio_status_fatal(status)) return status; +        actual_depth = out.params.fifo.op.config.actualDepth; +        actual_size = out.params.fifo.op.config.actualSize; -    actual_depth = out.params.fifo.op.config.actualDepth; -    actual_size = out.params.fifo.op.config.actualSize; +        status = _riok_proxy_ptr->map_fifo_memory(_fifo_channel, actual_size, _mem_map); -    status = _riok_proxy_ptr->map_fifo_memory(_fifo_channel, actual_size, _mem_map); +        if (nirio_status_not_fatal(status)) { +            _state = MAPPED; +        } +    } else { +        status = NiRio_Status_SoftwareFault; +    }      return status;  } @@ -90,9 +100,13 @@ template <typename data_t>  void nirio_fifo<data_t>::finalize()  {      boost::unique_lock<boost::recursive_mutex> lock(_mutex); -    if (!_mem_map.is_null()) { -        stop(); + +    //If the FIFO is started, the stop will change the state to MAPPED. +    stop(); + +    if (_state == MAPPED) {          _riok_proxy_ptr->unmap_fifo_memory(_mem_map); +        _state = UNMAPPED;    //Assume teardown succeeded      }  } @@ -104,16 +118,25 @@ nirio_status nirio_fifo<data_t>::start()      boost::unique_lock<boost::recursive_mutex> lock(_mutex); -    nirio_driver_iface::nirio_syncop_in_params_t in = {}; -    nirio_driver_iface::nirio_syncop_out_params_t out = {}; +    if (_state == STARTED) { +        //Do nothing. Already started. +    } else if (_state == MAPPED) { +        nirio_driver_iface::nirio_syncop_in_params_t in = {}; +        nirio_driver_iface::nirio_syncop_out_params_t out = {}; -    in.function    = nirio_driver_iface::NIRIO_FUNC::FIFO; -    in.subfunction = nirio_driver_iface::NIRIO_FIFO::START; +        in.function    = nirio_driver_iface::NIRIO_FUNC::FIFO; +        in.subfunction = nirio_driver_iface::NIRIO_FIFO::START; -    status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); -    if (nirio_status_not_fatal(status)) { -        _acquired_pending = 0; -        _expected_xfer_count = 0; +        in.params.fifo.channel = _fifo_channel; + +        status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); +        if (nirio_status_not_fatal(status)) { +            _state = STARTED; +            _acquired_pending = 0; +            _expected_xfer_count = 0; +        } +    } else { +        status = NiRio_Status_ResourceNotInitialized;      }      return status;  } @@ -125,15 +148,22 @@ nirio_status nirio_fifo<data_t>::stop()      if (!_riok_proxy_ptr) return NiRio_Status_ResourceNotInitialized;      boost::unique_lock<boost::recursive_mutex> lock(_mutex); -    if (_acquired_pending > 0) release(_acquired_pending); -    nirio_driver_iface::nirio_syncop_in_params_t in = {}; -    nirio_driver_iface::nirio_syncop_out_params_t out = {}; +    if (_state == STARTED) { +        if (_acquired_pending > 0) release(_acquired_pending); + +        nirio_driver_iface::nirio_syncop_in_params_t in = {}; +        nirio_driver_iface::nirio_syncop_out_params_t out = {}; -    in.function    = nirio_driver_iface::NIRIO_FUNC::FIFO; -    in.subfunction = nirio_driver_iface::NIRIO_FIFO::STOP; +        in.function    = nirio_driver_iface::NIRIO_FUNC::FIFO; +        in.subfunction = nirio_driver_iface::NIRIO_FIFO::STOP; -    status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); +        in.params.fifo.channel = _fifo_channel; + +        status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); + +        _state = MAPPED;    //Assume teardown succeeded +    }      return status;  } @@ -151,36 +181,40 @@ nirio_status nirio_fifo<data_t>::acquire(      boost::unique_lock<boost::recursive_mutex> lock(_mutex); -    nirio_driver_iface::nirio_syncop_in_params_t in = {}; -    uint32_t stuffed[2]; -    nirio_driver_iface::nirio_syncop_out_params_t out = {}; -    init_syncop_out_params(out, stuffed, sizeof(stuffed)); - -    in.function    = nirio_driver_iface::NIRIO_FUNC::FIFO; -    in.subfunction = nirio_driver_iface::NIRIO_FIFO::WAIT; - -    in.params.fifo.channel                   = _fifo_channel; -    in.params.fifo.op.wait.elementsRequested = static_cast<uint32_t>(elements_requested); -    in.params.fifo.op.wait.scalarType        = static_cast<uint32_t>(_datatype_info.scalar_type); -    in.params.fifo.op.wait.bitWidth          = _datatype_info.width * 8; -    in.params.fifo.op.wait.output            = _fifo_direction == OUTPUT_FIFO; -    in.params.fifo.op.wait.timeout           = timeout; - -    status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); - -    if (nirio_status_not_fatal(status)) { -        elements = static_cast<data_t*>(out.params.fifo.op.wait.elements.pointer); -        elements_acquired = stuffed[0]; -        elements_remaining = stuffed[1]; -        _acquired_pending = elements_acquired; - -        if (UHD_NIRIO_RX_FIFO_XFER_CHECK_EN && -            _riok_proxy_ptr->get_rio_quirks().rx_fifo_xfer_check_en() && -            get_direction() == INPUT_FIFO -        ) { -            _expected_xfer_count += static_cast<uint64_t>(elements_requested * sizeof(data_t)); -            status = _ensure_transfer_completed(timeout); +    if (_state == STARTED) { +        nirio_driver_iface::nirio_syncop_in_params_t in = {}; +        uint32_t stuffed[2]; +        nirio_driver_iface::nirio_syncop_out_params_t out = {}; +        init_syncop_out_params(out, stuffed, sizeof(stuffed)); + +        in.function    = nirio_driver_iface::NIRIO_FUNC::FIFO; +        in.subfunction = nirio_driver_iface::NIRIO_FIFO::WAIT; + +        in.params.fifo.channel                   = _fifo_channel; +        in.params.fifo.op.wait.elementsRequested = static_cast<uint32_t>(elements_requested); +        in.params.fifo.op.wait.scalarType        = static_cast<uint32_t>(_datatype_info.scalar_type); +        in.params.fifo.op.wait.bitWidth          = _datatype_info.width * 8; +        in.params.fifo.op.wait.output            = _fifo_direction == OUTPUT_FIFO; +        in.params.fifo.op.wait.timeout           = timeout; + +        status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); + +        if (nirio_status_not_fatal(status)) { +            elements = static_cast<data_t*>(out.params.fifo.op.wait.elements.pointer); +            elements_acquired = stuffed[0]; +            elements_remaining = stuffed[1]; +            _acquired_pending = elements_acquired; + +            if (UHD_NIRIO_RX_FIFO_XFER_CHECK_EN && +                _riok_proxy_ptr->get_rio_quirks().rx_fifo_xfer_check_en() && +                get_direction() == INPUT_FIFO +            ) { +                _expected_xfer_count += static_cast<uint64_t>(elements_requested * sizeof(data_t)); +                status = _ensure_transfer_completed(timeout); +            }          } +    } else { +        status = NiRio_Status_ResourceNotInitialized;      }      return status; @@ -194,17 +228,21 @@ nirio_status nirio_fifo<data_t>::release(const size_t elements)      boost::unique_lock<boost::recursive_mutex> lock(_mutex); -    nirio_driver_iface::nirio_syncop_in_params_t in = {}; -    nirio_driver_iface::nirio_syncop_out_params_t out = {}; +    if (_state == STARTED) { +        nirio_driver_iface::nirio_syncop_in_params_t in = {}; +        nirio_driver_iface::nirio_syncop_out_params_t out = {}; -    in.function    = nirio_driver_iface::NIRIO_FUNC::FIFO; -    in.subfunction = nirio_driver_iface::NIRIO_FIFO::GRANT; +        in.function    = nirio_driver_iface::NIRIO_FUNC::FIFO; +        in.subfunction = nirio_driver_iface::NIRIO_FIFO::GRANT; -    in.params.fifo.channel           = _fifo_channel; -    in.params.fifo.op.grant.elements = static_cast<uint32_t>(elements); +        in.params.fifo.channel           = _fifo_channel; +        in.params.fifo.op.grant.elements = static_cast<uint32_t>(elements); -    status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); -    _acquired_pending = 0; +        status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); +        _acquired_pending = 0; +    } else { +        status = NiRio_Status_ResourceNotInitialized; +    }      return status;  } @@ -222,23 +260,27 @@ nirio_status nirio_fifo<data_t>::read(      boost::unique_lock<boost::recursive_mutex> lock(_mutex); -    nirio_driver_iface::nirio_syncop_in_params_t in = {}; -    nirio_driver_iface::nirio_syncop_out_params_t out = {}; -    init_syncop_out_params(out, buf, num_elements * _datatype_info.width); +    if (_state == STARTED) { +        nirio_driver_iface::nirio_syncop_in_params_t in = {}; +        nirio_driver_iface::nirio_syncop_out_params_t out = {}; +        init_syncop_out_params(out, buf, num_elements * _datatype_info.width); -    in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; -    in.subfunction = nirio_driver_iface::NIRIO_FIFO::READ; +        in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; +        in.subfunction = nirio_driver_iface::NIRIO_FIFO::READ; -    in.params.fifo.channel = _fifo_channel; -    in.params.fifo.op.readWithDataType.timeout = timeout; -    in.params.fifo.op.readWithDataType.scalarType = static_cast<uint32_t>(_datatype_info.scalar_type); -    in.params.fifo.op.readWithDataType.bitWidth = _datatype_info.width * 8; +        in.params.fifo.channel = _fifo_channel; +        in.params.fifo.op.readWithDataType.timeout = timeout; +        in.params.fifo.op.readWithDataType.scalarType = static_cast<uint32_t>(_datatype_info.scalar_type); +        in.params.fifo.op.readWithDataType.bitWidth = _datatype_info.width * 8; -    status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); +        status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); -    if (nirio_status_not_fatal(status) || status == NiRio_Status_FifoTimeout) { -        num_read = out.params.fifo.op.read.numberRead; -        num_remaining = out.params.fifo.op.read.numberRemaining; +        if (nirio_status_not_fatal(status) || status == NiRio_Status_FifoTimeout) { +            num_read = out.params.fifo.op.read.numberRead; +            num_remaining = out.params.fifo.op.read.numberRemaining; +        } +    } else { +        status = NiRio_Status_ResourceNotInitialized;      }      return status; @@ -256,22 +298,26 @@ nirio_status nirio_fifo<data_t>::write(      boost::unique_lock<boost::recursive_mutex> lock(_mutex); -    nirio_driver_iface::nirio_syncop_in_params_t in = {}; -    init_syncop_in_params(in, buf, num_elements * _datatype_info.width); -    nirio_driver_iface::nirio_syncop_out_params_t out = {}; +    if (_state == STARTED) { +        nirio_driver_iface::nirio_syncop_in_params_t in = {}; +        init_syncop_in_params(in, buf, num_elements * _datatype_info.width); +        nirio_driver_iface::nirio_syncop_out_params_t out = {}; -    in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; -    in.subfunction = nirio_driver_iface::NIRIO_FIFO::WRITE; +        in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; +        in.subfunction = nirio_driver_iface::NIRIO_FIFO::WRITE; -    in.params.fifo.channel = _fifo_channel; -    in.params.fifo.op.writeWithDataType.timeout = timeout; -    in.params.fifo.op.readWithDataType.scalarType = static_cast<uint32_t>(_datatype_info.scalar_type); -    in.params.fifo.op.readWithDataType.bitWidth = _datatype_info.width * 8; +        in.params.fifo.channel = _fifo_channel; +        in.params.fifo.op.writeWithDataType.timeout = timeout; +        in.params.fifo.op.readWithDataType.scalarType = static_cast<uint32_t>(_datatype_info.scalar_type); +        in.params.fifo.op.readWithDataType.bitWidth = _datatype_info.width * 8; -    status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); +        status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); -    if (nirio_status_not_fatal(status) || status == NiRio_Status_FifoTimeout) { -        num_remaining = out.params.fifo.op.write.numberRemaining; +        if (nirio_status_not_fatal(status) || status == NiRio_Status_FifoTimeout) { +            num_remaining = out.params.fifo.op.write.numberRemaining; +        } +    } else { +        status = NiRio_Status_ResourceNotInitialized;      }      return status; diff --git a/host/include/uhd/transport/nirio/nirio_quirks.h b/host/include/uhd/transport/nirio/nirio_quirks.h index 326eeeb8c..ed4f72e7f 100644 --- a/host/include/uhd/transport/nirio/nirio_quirks.h +++ b/host/include/uhd/transport/nirio/nirio_quirks.h @@ -24,8 +24,8 @@  //Quirk#1: We need to verify RX zero-copy data transfers from the RIO  //         driver if we are in full duplex mode. -//         This option allows disabling this quirk by compiling it out. -#define UHD_NIRIO_RX_FIFO_XFER_CHECK_EN 1 +//         This option allows enabling this quirk. +#define UHD_NIRIO_RX_FIFO_XFER_CHECK_EN 0  namespace uhd { namespace niusrprio { diff --git a/host/include/uhd/types/metadata.hpp b/host/include/uhd/types/metadata.hpp index 6a79720d0..51a2b7c43 100644 --- a/host/include/uhd/types/metadata.hpp +++ b/host/include/uhd/types/metadata.hpp @@ -1,5 +1,5 @@  // -// Copyright 2010-2012 Ettus Research LLC +// Copyright 2010-2012,2014 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 @@ -117,6 +117,20 @@ namespace uhd{          //! Out of sequence.  The transport has either dropped a packet or received data out of order.          bool out_of_sequence; + +        /*! +         * Convert a rx_metadata_t into a pretty print string. +	 * +	 * \param compact Set to false for a more verbose output. +         * \return a printable string representing the metadata. +         */ +        std::string to_pp_string(bool compact=true) const; + +        /*! +         * Similar to C's strerror() function, creates a std::string describing the error code. +         * \return a printable string representing the error. +         */ +	std::string strerror(void) const;      };      /*! diff --git a/host/include/uhd/usrp/multi_usrp.hpp b/host/include/uhd/usrp/multi_usrp.hpp index aac40efe5..883e4da3d 100644 --- a/host/include/uhd/usrp/multi_usrp.hpp +++ b/host/include/uhd/usrp/multi_usrp.hpp @@ -119,14 +119,10 @@ public:      virtual device::sptr get_device(void) = 0;      //! Convenience method to get a RX streamer. See also uhd::device::get_rx_stream(). -    rx_streamer::sptr get_rx_stream(const stream_args_t &args){ -        return this->get_device()->get_rx_stream(args); -    } +    virtual rx_streamer::sptr get_rx_stream(const stream_args_t &args) = 0;      //! Convenience method to get a TX streamer. See also uhd::device::get_rx_stream(). -    tx_streamer::sptr get_tx_stream(const stream_args_t &args){ -        return this->get_device()->get_tx_stream(args); -    } +    virtual tx_streamer::sptr get_tx_stream(const stream_args_t &args) = 0;      /*!       * Returns identifying information about this USRP's configuration. diff --git a/host/include/uhd/utils/CMakeLists.txt b/host/include/uhd/utils/CMakeLists.txt index c0991b3ce..e9633286f 100644 --- a/host/include/uhd/utils/CMakeLists.txt +++ b/host/include/uhd/utils/CMakeLists.txt @@ -22,6 +22,7 @@ UHD_INSTALL(FILES      atomic.hpp      byteswap.hpp      byteswap.ipp +    cast.hpp      csv.hpp      gain_group.hpp      images.hpp diff --git a/host/include/uhd/utils/cast.hpp b/host/include/uhd/utils/cast.hpp new file mode 100644 index 000000000..9db92c526 --- /dev/null +++ b/host/include/uhd/utils/cast.hpp @@ -0,0 +1,43 @@ +// +// Copyright 2014 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_UTILS_CAST_HPP +#define INCLUDED_UHD_UTILS_CAST_HPP + +#include <uhd/config.hpp> +#include <string> +#include <sstream> + +namespace uhd{ namespace cast{ +    //! Convert a hexadecimal string into a value. +    // +    // Example: +    //     boost::uint16_t x = hexstr_cast<boost::uint16_t>("0xDEADBEEF"); +    // Uses stringstream. +    template<typename T> inline T hexstr_cast(const std::string &in) +    { +        T x; +        std::stringstream ss; +        ss << std::hex << in; +        ss >> x; +        return x; +    } + +}} //namespace uhd::cast + +#endif /* INCLUDED_UHD_UTILS_CAST_HPP */ + | 
