diff options
| -rw-r--r-- | firmware/microblaze/apps/Makefile.am | 2 | ||||
| -rw-r--r-- | firmware/microblaze/apps/txrx.c | 5 | ||||
| -rw-r--r-- | host/CMakeLists.txt | 9 | ||||
| -rw-r--r-- | host/include/uhd/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | host/include/uhd/device.hpp | 33 | ||||
| -rw-r--r-- | host/include/uhd/metadata.hpp | 47 | ||||
| -rw-r--r-- | host/include/uhd/transport/udp.hpp | 17 | ||||
| -rw-r--r-- | host/lib/transport/udp.cpp | 20 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.cpp | 74 | ||||
| -rw-r--r-- | host/lib/usrp/usrp2/usrp2_impl.hpp | 4 | 
10 files changed, 189 insertions, 23 deletions
| diff --git a/firmware/microblaze/apps/Makefile.am b/firmware/microblaze/apps/Makefile.am index 6d993ef8c..ff426cf8c 100644 --- a/firmware/microblaze/apps/Makefile.am +++ b/firmware/microblaze/apps/Makefile.am @@ -21,7 +21,7 @@ include $(top_srcdir)/Makefile.common  LDADD = $(top_srcdir)/lib/libu2fw.a -AM_CFLAGS += -I$(top_srcdir)/../../host/lib/usrp/mboard +AM_CFLAGS += -I$(top_srcdir)/../../host/lib/usrp  noinst_PROGRAMS = txrx.elf diff --git a/firmware/microblaze/apps/txrx.c b/firmware/microblaze/apps/txrx.c index 77c8e498c..16aa8eab2 100644 --- a/firmware/microblaze/apps/txrx.c +++ b/firmware/microblaze/apps/txrx.c @@ -159,7 +159,10 @@ void handle_udp_data_packet(      unsigned char *payload, int payload_len  ){      //TODO store the reply port -    _is_data = true; + +    //forward this data to the dsp when the payload is sufficient +    //the small payload is used to give the device the udp source port +    _is_data = payload_len > sizeof(uint32_t);  }  #define OTW_GPIO_BANK_TO_NUM(bank) \ diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index 70c04631b..30f4789a3 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -73,6 +73,15 @@ INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})  LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})  ######################################################################## +# Setup Endianess +######################################################################## +INCLUDE(TestBigEndian) +TEST_BIG_ENDIAN(HAVE_BIG_ENDIAN) +IF(HAVE_BIG_ENDIAN) +    ADD_DEFINITIONS("-DHAVE_BIG_ENDIAN=/* */") +ENDIF(HAVE_BIG_ENDIAN) + +########################################################################  # Create Uninstall Target  ########################################################################  CONFIGURE_FILE( diff --git a/host/include/uhd/CMakeLists.txt b/host/include/uhd/CMakeLists.txt index 006c54f22..e87f74291 100644 --- a/host/include/uhd/CMakeLists.txt +++ b/host/include/uhd/CMakeLists.txt @@ -24,6 +24,7 @@ INSTALL(FILES      device_addr.hpp      dict.hpp      gain_handler.hpp +    metadata.hpp      props.hpp      shared_iovec.hpp      time_spec.hpp diff --git a/host/include/uhd/device.hpp b/host/include/uhd/device.hpp index dfbfbd7c0..da58d4f85 100644 --- a/host/include/uhd/device.hpp +++ b/host/include/uhd/device.hpp @@ -20,13 +20,12 @@  #include <uhd/device_addr.hpp>  #include <uhd/props.hpp> +#include <uhd/metadata.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{ @@ -72,9 +71,33 @@ public:       */      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; +    /*! +     * Send a buffer containing IF data with its metadata. +     * +     * \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) +     * \return the number of bytes sent +     */ +    virtual size_t send( +        const boost::asio::const_buffer &buff, +        const metadata_t &metadata, +        const std::string &type = "32fc" +    ) = 0; + +    /*! +     * Receive a buffer containing IF data and its metadata. +     * +     * \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) +     * \return the number of bytes received +     */ +    virtual size_t recv( +        const boost::asio::mutable_buffer &buff, +        metadata_t &metadata, +        const std::string &type = "32fc" +    ) = 0;  };  } //namespace uhd diff --git a/host/include/uhd/metadata.hpp b/host/include/uhd/metadata.hpp new file mode 100644 index 000000000..43b91d1b0 --- /dev/null +++ b/host/include/uhd/metadata.hpp @@ -0,0 +1,47 @@ +// +// 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_METADATA_HPP +#define INCLUDED_UHD_METADATA_HPP + +#include <uhd/time_spec.hpp> + +namespace uhd{ + +/*! + * Metadata structure for describing the IF data. + * Includes stream ID, time specification, and burst flags. + * The receive routines will convert IF data headers into metadata. + * The send routines will convert the metadata to IF data headers. + */ +struct metadata_t{ +    uint32_t stream_id; +    time_spec_t time_spec; +    bool start_of_burst; +    bool end_of_burst; + +    metadata_t(void){ +        stream_id = 0; +        time_spec = time_spec_t(); +        start_of_burst = false; +        end_of_burst = false; +    } +}; + +} //namespace uhd + +#endif /* INCLUDED_UHD_METADATA_HPP */ diff --git a/host/include/uhd/transport/udp.hpp b/host/include/uhd/transport/udp.hpp index 554234b43..07d84e62a 100644 --- a/host/include/uhd/transport/udp.hpp +++ b/host/include/uhd/transport/udp.hpp @@ -41,18 +41,31 @@ public:      /*!       * Send a vector of buffer (like send_msg). +     * Blocks until the data is sent.       * \param buffs a vector of asio buffers +     * \return the number of bytes sent       */ -    virtual void send(const std::vector<boost::asio::const_buffer> &buffs) = 0; +    virtual size_t send(const std::vector<boost::asio::const_buffer> &buffs) = 0;      /*!       * Send a single buffer. +     * Blocks until the data is sent.       * \param buff single asio buffer +     * \return the number of bytes sent       */ -    virtual void send(const boost::asio::const_buffer &buff) = 0; +    virtual size_t send(const boost::asio::const_buffer &buff) = 0; + +    /*! +     * Receive a buffer. Write into the memory provided. +     * Returns empty when data is not available. +     * \param buff a mutable buffer to receive into +     * \return the number of bytes received. +     */ +    virtual size_t recv(const boost::asio::mutable_buffer &buff) = 0;      /*!       * Receive a buffer. The memory is managed internally. +     * Returns zero when data is not available.       * Calling recv will invalidate the buffer of the previous recv.       * \return a shared iovec with allocated memory       */ diff --git a/host/lib/transport/udp.cpp b/host/lib/transport/udp.cpp index af60760a5..fca4dd7d6 100644 --- a/host/lib/transport/udp.cpp +++ b/host/lib/transport/udp.cpp @@ -17,7 +17,6 @@  #include <uhd/transport/udp.hpp>  #include <boost/format.hpp> -#include <boost/assign/list_of.hpp>  #include <iostream>  /*********************************************************************** @@ -30,8 +29,9 @@ public:      ~udp_impl(void);      //send/recv -    void send(const std::vector<boost::asio::const_buffer> &buffs); -    void send(const boost::asio::const_buffer &buff); +    size_t send(const std::vector<boost::asio::const_buffer> &buffs); +    size_t send(const boost::asio::const_buffer &buff); +    size_t recv(const boost::asio::mutable_buffer &buff);      uhd::shared_iovec recv(void);  private: @@ -79,13 +79,17 @@ udp_impl::~udp_impl(void){      delete _socket;  } -void udp_impl::send(const std::vector<boost::asio::const_buffer> &buffs){ -    _socket->send_to(buffs, _receiver_endpoint); +size_t udp_impl::send(const std::vector<boost::asio::const_buffer> &buffs){ +    return _socket->send_to(buffs, _receiver_endpoint);  } -void udp_impl::send(const boost::asio::const_buffer &buff){ -    std::vector<boost::asio::const_buffer> buffs = boost::assign::list_of(buff); -    send(buffs); +size_t udp_impl::send(const boost::asio::const_buffer &buff){ +    return _socket->send_to(boost::asio::buffer(buff), _receiver_endpoint); +} + +size_t udp_impl::recv(const boost::asio::mutable_buffer &buff){ +    if (_socket->available() == 0) return 0; +    return _socket->receive_from(boost::asio::buffer(buff), _sender_endpoint);  }  uhd::shared_iovec udp_impl::recv(void){ diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index f44964394..47bf06aff 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -130,6 +130,10 @@ usrp2_impl::usrp2_impl(      //init the tx and rx dboards (do last)      dboard_init(); +    //send a small data packet so the usrp2 knows the udp source port +    uint32_t zero_data = 0; +    _data_transport->send(boost::asio::buffer(&zero_data, sizeof(zero_data))); +  }  usrp2_impl::~usrp2_impl(void){ @@ -204,10 +208,72 @@ void usrp2_impl::set(const wax::obj &, const wax::obj &){  /***********************************************************************   * IO Interface   **********************************************************************/ -void usrp2_impl::send_raw(const std::vector<boost::asio::const_buffer> &){ -    return; +static const float float_scale_factor = pow(2.0, 15); + +size_t usrp2_impl::send( +    const boost::asio::const_buffer &buff, +    const uhd::metadata_t &metadata, +    const std::string &type +){ +    if (type == "fc32"){ +        //extract the buffer elements +        const float *float_buff = boost::asio::buffer_cast<const float*>(buff); +        const size_t buff_len = boost::asio::buffer_size(buff)/sizeof(float); + +        //convert floats into the shorts buffer +        int16_t *shorts_buff = new int16_t[buff_len]; +        for (size_t i = 0; i < buff_len; i++){ +            shorts_buff[i] = float_buff[i]*float_scale_factor; +        } + +        //send from a buffer of shorts +        size_t bytes_sent = send( +            boost::asio::buffer(shorts_buff, buff_len*sizeof(int16_t)), +            metadata, "sc16" +        ); + +        //cleanup +        delete [] shorts_buff; +        return bytes_sent; +    } + +    if (type == "sc16"){ +        throw std::runtime_error("not implemented"); +    } + +    throw std::runtime_error(str(boost::format("usrp2 send: cannot handle type \"%s\"") % type));  } -uhd::shared_iovec usrp2_impl::recv_raw(void){ -    throw std::runtime_error("not implemented"); +size_t usrp2_impl::recv( +    const boost::asio::mutable_buffer &buff, +    uhd::metadata_t &metadata, +    const std::string &type +){ +    if (type == "fc32"){ +        //extract the buffer elements +        float *float_buff = boost::asio::buffer_cast<float*>(buff); +        const size_t buff_len = boost::asio::buffer_size(buff)/sizeof(float); + +        //receive into a buffer of shorts +        int16_t *shorts_buff = new int16_t[buff_len]; +        size_t bytes_received = recv( +            boost::asio::buffer(shorts_buff, buff_len*sizeof(int16_t)), +            metadata, "sc16" +        ); + +        //convert floats into the shorts buffer +        for (size_t i = 0; i < bytes_received/sizeof(int16_t); i++){ +            float_buff[i] = shorts_buff[i]/float_scale_factor; +        } + +        //cleanup +        delete [] shorts_buff; +        return bytes_received; +    } + +    if (type == "sc16"){ +        throw std::runtime_error("not implemented"); +    } + +    throw std::runtime_error(str(boost::format("usrp2 recv: cannot handle type \"%s\"") % type));  } diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 2545efd58..2476bcf1d 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -98,8 +98,8 @@ public:      double get_master_clock_freq(void);      //the io interface -    void send_raw(const std::vector<boost::asio::const_buffer> &); -    uhd::shared_iovec recv_raw(void); +    size_t send(const boost::asio::const_buffer &, const uhd::metadata_t &, const std::string &); +    size_t recv(const boost::asio::mutable_buffer &, uhd::metadata_t &, const std::string &);  private:      //udp transports for control and data | 
