diff options
author | Josh Blum <josh@joshknows.com> | 2010-03-30 14:07:19 -0700 |
---|---|---|
committer | Josh Blum <josh@joshknows.com> | 2010-03-30 14:07:19 -0700 |
commit | f9be69cae7c0fd9bca8b310ff79dd6aad958dc2b (patch) | |
tree | 42c05c3501de70c7eddf1aa46c301a6216d270f9 /host | |
parent | 5a08586157ed23ebc1344583d21fa56fb27cbe52 (diff) | |
download | uhd-f9be69cae7c0fd9bca8b310ff79dd6aad958dc2b.tar.gz uhd-f9be69cae7c0fd9bca8b310ff79dd6aad958dc2b.tar.bz2 uhd-f9be69cae7c0fd9bca8b310ff79dd6aad958dc2b.zip |
Added io type and otw type for describing types.
Diffstat (limited to 'host')
-rw-r--r-- | host/examples/rx_timed_samples.cpp | 5 | ||||
-rw-r--r-- | host/include/uhd/device.hpp | 10 | ||||
-rw-r--r-- | host/include/uhd/types/CMakeLists.txt | 2 | ||||
-rw-r--r-- | host/include/uhd/types/clock_config.hpp | 16 | ||||
-rw-r--r-- | host/include/uhd/types/io_type.hpp | 69 | ||||
-rw-r--r-- | host/include/uhd/types/otw_type.hpp | 63 | ||||
-rw-r--r-- | host/lib/types.cpp | 35 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/io_impl.cpp | 68 | ||||
-rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.hpp | 4 |
9 files changed, 221 insertions, 51 deletions
diff --git a/host/examples/rx_timed_samples.cpp b/host/examples/rx_timed_samples.cpp index 5d4b5a68d..88e112584 100644 --- a/host/examples/rx_timed_samples.cpp +++ b/host/examples/rx_timed_samples.cpp @@ -80,7 +80,10 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ while(num_acc_samps < total_num_samps){ uhd::rx_metadata_t md; std::complex<float> buff[1000]; - size_t num_rx_samps = dev->recv(boost::asio::buffer(buff, sizeof(buff)), md, "32fc"); + size_t num_rx_samps = dev->recv( + boost::asio::buffer(buff, sizeof(buff)), + md, uhd::io_type_t::COMPLEX_FLOAT32 + ); if (num_rx_samps == 0) continue; //wait for packets with contents std::cout << boost::format("Got packet: %u samples, %u secs, %u ticks") diff --git a/host/include/uhd/device.hpp b/host/include/uhd/device.hpp index bab8afca6..1d0360799 100644 --- a/host/include/uhd/device.hpp +++ b/host/include/uhd/device.hpp @@ -21,7 +21,7 @@ #include <uhd/config.hpp> #include <uhd/types/device_addr.hpp> #include <uhd/types/metadata.hpp> -#include <uhd/props.hpp> +#include <uhd/types/io_type.hpp> #include <uhd/wax.hpp> #include <boost/utility.hpp> #include <boost/shared_ptr.hpp> @@ -91,13 +91,13 @@ public: * * \param buff a buffer pointing to some read-only memory * \param metadata data describing the buffer's contents - * \param the type of data loaded in the buffer (32fc, 16sc) + * \param io_type the type of data loaded in the buffer * \return the number of samples sent */ virtual size_t send( const boost::asio::const_buffer &buff, const tx_metadata_t &metadata, - const std::string &type = "32fc" + const io_type_t &io_type ) = 0; /*! @@ -123,13 +123,13 @@ public: * * \param buff the buffer to fill with IF data * \param metadata data to fill describing the buffer - * \param the type of data to fill into the buffer (32fc, 16sc) + * \param io_type the type of data to fill into the buffer * \return the number of samples received */ virtual size_t recv( const boost::asio::mutable_buffer &buff, rx_metadata_t &metadata, - const std::string &type = "32fc" + const io_type_t &io_type ) = 0; }; diff --git a/host/include/uhd/types/CMakeLists.txt b/host/include/uhd/types/CMakeLists.txt index 10262dd65..e4cdf2cef 100644 --- a/host/include/uhd/types/CMakeLists.txt +++ b/host/include/uhd/types/CMakeLists.txt @@ -20,8 +20,10 @@ INSTALL(FILES clock_config.hpp device_addr.hpp dict.hpp + io_type.hpp mac_addr.hpp metadata.hpp + otw_type.hpp ranges.hpp stream_cmd.hpp time_spec.hpp diff --git a/host/include/uhd/types/clock_config.hpp b/host/include/uhd/types/clock_config.hpp index 8b2fea016..42d74ad90 100644 --- a/host/include/uhd/types/clock_config.hpp +++ b/host/include/uhd/types/clock_config.hpp @@ -29,18 +29,18 @@ namespace uhd{ */ struct UHD_API clock_config_t{ enum ref_source_t { - REF_INT, //internal reference - REF_SMA, //external sma port - REF_MIMO //mimo cable (usrp2 only) + REF_INT = 'i', //internal reference + REF_SMA = 's', //external sma port + REF_MIMO = 'm' //mimo cable (usrp2 only) } ref_source; enum pps_source_t { - PPS_INT, //there is no internal - PPS_SMA, //external sma port - PPS_MIMO //mimo cable (usrp2 only) + PPS_INT = 'i', //there is no internal + PPS_SMA = 's', //external sma port + PPS_MIMO = 'm' //mimo cable (usrp2 only) } pps_source; enum pps_polarity_t { - PPS_NEG, //negative edge - PPS_POS //positive edge + PPS_NEG = 'n', //negative edge + PPS_POS = 'p' //positive edge } pps_polarity; clock_config_t(void); }; diff --git a/host/include/uhd/types/io_type.hpp b/host/include/uhd/types/io_type.hpp new file mode 100644 index 000000000..930394d1b --- /dev/null +++ b/host/include/uhd/types/io_type.hpp @@ -0,0 +1,69 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TYPES_IO_TYPE_HPP +#define INCLUDED_UHD_TYPES_IO_TYPE_HPP + +#include <uhd/config.hpp> + +namespace uhd{ + + /*! + * Used to specify the IO type with device send/recv. + */ + class UHD_API io_type_t{ + public: + + /*! + * Built in IO types known to the system. + */ + enum tid_t{ + CUSTOM_TYPE = '?', + COMPLEX_FLOAT32 = 'f', + COMPLEX_INT16 = 's', + COMPLEX_INT8 = 'b' + }; + + /*! + * The size of this io type in bytes. + */ + const size_t size; + + /*! + * The type id of this io type. + * Good for using with switch statements. + */ + const tid_t tid; + + /*! + * Create an io type from a built-in type id. + * \param tid a type id known to the system + */ + io_type_t(tid_t tid); + + /*! + * Create an io type from attributes. + * The tid will be set to custom. + * \param size the size in bytes + */ + io_type_t(size_t size); + + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_IO_TYPE_HPP */ diff --git a/host/include/uhd/types/otw_type.hpp b/host/include/uhd/types/otw_type.hpp new file mode 100644 index 000000000..f10664584 --- /dev/null +++ b/host/include/uhd/types/otw_type.hpp @@ -0,0 +1,63 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TYPES_OTW_TYPE_HPP +#define INCLUDED_UHD_TYPES_OTW_TYPE_HPP + +#include <uhd/config.hpp> + +namespace uhd{ + + /*! + * Description for over-the-wire integers: + * The DSP units in the FPGA deal with signed 16-bit integers. + * The width and shift define the translation between OTW and DSP, + * defined by the following relation: otw_int = dsp_int >> shift + * + * Note: possible combinations of width, shift, and byteorder + * depend on the internals of the FPGA. Not all are supported! + */ + struct UHD_API otw_type_t{ + + /*! + * Width of an over-the-wire integer in bits. + */ + size_t width; //in bits + + /*! + * Shift of an over-the-wire integer in bits. + * otw_int = dsp_int >> shift + * dsp_int = otw_int << shift + */ + size_t shift; //in bits + + /*! + * Constants for byte order (borrowed from numpy's dtype) + */ + enum /*bo_t*/ { + BO_NATIVE = '=', + BO_LITTLE_ENDIAN = '<', + BO_BIG_ENDIAN = '>', + BO_NOT_APPLICABLE = '|' + } byteorder; + + otw_type_t(void); + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_OTW_TYPE_HPP */ diff --git a/host/lib/types.cpp b/host/lib/types.cpp index 3fde40596..bf9f8b895 100644 --- a/host/lib/types.cpp +++ b/host/lib/types.cpp @@ -23,10 +23,14 @@ #include <uhd/types/time_spec.hpp> #include <uhd/types/device_addr.hpp> #include <uhd/types/mac_addr.hpp> +#include <uhd/types/otw_type.hpp> +#include <uhd/types/io_type.hpp> #include <boost/algorithm/string.hpp> #include <boost/foreach.hpp> #include <boost/format.hpp> +#include <boost/cstdint.hpp> #include <stdexcept> +#include <complex> using namespace uhd; @@ -210,3 +214,34 @@ std::string mac_addr_t::to_string(void) const{ % int(to_bytes()[3]) % int(to_bytes()[4]) % int(to_bytes()[5]) ); } + +/*********************************************************************** + * otw type + **********************************************************************/ +otw_type_t::otw_type_t(void){ + width = 0; + shift = 0; + byteorder = BO_NATIVE; +} + +/*********************************************************************** + * io type + **********************************************************************/ +static size_t tid_to_size(io_type_t::tid_t tid){ + switch(tid){ + case io_type_t::COMPLEX_FLOAT32: return sizeof(std::complex<float>); + case io_type_t::COMPLEX_INT16: return sizeof(std::complex<boost::int16_t>); + case io_type_t::COMPLEX_INT8: return sizeof(std::complex<boost::int8_t>); + default: throw std::runtime_error("unknown io type tid"); + } +} + +io_type_t::io_type_t(tid_t tid) +: size(tid_to_size(tid)), tid(tid){ + /* NOP */ +} + +io_type_t::io_type_t(size_t size) +: size(size), tid(CUSTOM_TYPE){ + /* NOP */ +} diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index 280f124d2..c87884ebb 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -172,46 +172,43 @@ void usrp2_impl::recv_raw(rx_metadata_t &metadata){ size_t usrp2_impl::send( const asio::const_buffer &buff, const tx_metadata_t &metadata, - const std::string &type + const io_type_t &io_type ){ boost::uint32_t tx_mem[_mtu/sizeof(boost::uint32_t)]; - boost::uint32_t *items = tx_mem + vrt::max_header_words32; //offset for data - size_t num_samps = _max_tx_samples_per_packet; - - //calculate the number of samples to be copied - //and copy the samples into the send buffer - if (type == "32fc"){ - num_samps = std::min(asio::buffer_size(buff)/sizeof(fc32_t), num_samps); - host_floats_to_usrp2_items(items, asio::buffer_cast<const fc32_t*>(buff), num_samps); - } - else if (type == "16sc"){ - num_samps = std::min(asio::buffer_size(buff)/sizeof(sc16_t), num_samps); - host_items_to_usrp2_items(items, asio::buffer_cast<const boost::uint32_t*>(buff), num_samps); - } - else{ - throw std::runtime_error(str(boost::format("usrp2 send: cannot handle type \"%s\"") % type)); - } + size_t num_samps = std::min( + asio::buffer_size(buff)/io_type.size, + size_t(_max_tx_samples_per_packet) + ); - boost::uint32_t vrt_hdr[vrt::max_header_words32]; size_t num_header_words32, num_packet_words32; size_t packet_count = _tx_stream_id_to_packet_seq[metadata.stream_id]++; //pack metadata into a vrt header vrt::pack( metadata, //input - vrt_hdr, //output + tx_mem, //output num_header_words32, //output num_samps, //input num_packet_words32, //output packet_count //input ); - //copy in the vrt header (yes we left space) - items -= num_header_words32; - std::memcpy(items, vrt_hdr, num_header_words32*sizeof(boost::uint32_t)); + boost::uint32_t *items = tx_mem + num_header_words32; //offset for data + + //copy the samples into the send buffer + switch(io_type.tid){ + case io_type_t::COMPLEX_FLOAT32: + host_floats_to_usrp2_items(items, asio::buffer_cast<const fc32_t*>(buff), num_samps); + break; + case io_type_t::COMPLEX_INT16: + host_items_to_usrp2_items(items, asio::buffer_cast<const boost::uint32_t*>(buff), num_samps); + break; + default: + throw std::runtime_error(str(boost::format("usrp2 send: cannot handle type \"%c\"") % io_type.tid)); + } //send and return number of samples - _data_transport->send(asio::buffer(items, num_packet_words32*sizeof(boost::uint32_t))); + _data_transport->send(asio::buffer(tx_mem, num_packet_words32*sizeof(boost::uint32_t))); return num_samps; } @@ -221,7 +218,7 @@ size_t usrp2_impl::send( size_t usrp2_impl::recv( const asio::mutable_buffer &buff, rx_metadata_t &metadata, - const std::string &type + const io_type_t &io_type ){ //perform a receive if no rx data is waiting to be copied if (asio::buffer_size(_rx_copy_buff) == 0){ @@ -237,21 +234,22 @@ size_t usrp2_impl::recv( //and a pointer into the usrp2 received items memory size_t bytes_to_copy = asio::buffer_size(_rx_copy_buff); if (bytes_to_copy == 0) return 0; //nothing to receive - size_t num_samps = bytes_to_copy/sizeof(boost::uint32_t); + size_t num_samps = std::min( + asio::buffer_size(buff)/io_type.size, + bytes_to_copy/sizeof(boost::uint32_t) + ); const boost::uint32_t *items = asio::buffer_cast<const boost::uint32_t*>(_rx_copy_buff); - //calculate the number of samples to be copied - //and copy the samples from the recv buffer - if (type == "32fc"){ - num_samps = std::min(asio::buffer_size(buff)/sizeof(fc32_t), num_samps); + //copy the samples from the recv buffer + switch(io_type.tid){ + case io_type_t::COMPLEX_FLOAT32: usrp2_items_to_host_floats(asio::buffer_cast<fc32_t*>(buff), items, num_samps); - } - else if (type == "16sc"){ - num_samps = std::min(asio::buffer_size(buff)/sizeof(sc16_t), num_samps); + break; + case io_type_t::COMPLEX_INT16: usrp2_items_to_host_items(asio::buffer_cast<boost::uint32_t*>(buff), items, num_samps); - } - else{ - throw std::runtime_error(str(boost::format("usrp2 recv: cannot handle type \"%s\"") % type)); + break; + default: + throw std::runtime_error(str(boost::format("usrp2 recv: cannot handle type \"%c\"") % io_type.tid)); } //update the rx copy buffer to reflect the bytes copied diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 6535e7049..3468a0cf1 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -106,8 +106,8 @@ public: double get_master_clock_freq(void); //the io interface - size_t send(const boost::asio::const_buffer &, const uhd::tx_metadata_t &, const std::string &); - size_t recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const std::string &); + size_t send(const boost::asio::const_buffer &, const uhd::tx_metadata_t &, const uhd::io_type_t &); + size_t recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const uhd::io_type_t &); private: //device properties interface |