aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--host/examples/rx_timed_samples.cpp5
-rw-r--r--host/include/uhd/device.hpp10
-rw-r--r--host/include/uhd/types/CMakeLists.txt2
-rw-r--r--host/include/uhd/types/clock_config.hpp16
-rw-r--r--host/include/uhd/types/io_type.hpp69
-rw-r--r--host/include/uhd/types/otw_type.hpp63
-rw-r--r--host/lib/types.cpp35
-rw-r--r--host/lib/usrp/usrp2/io_impl.cpp68
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.hpp4
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