From 551426b72672379faa56302eb3d3e19d12c41aec Mon Sep 17 00:00:00 2001
From: Josh Blum <josh@joshknows.com>
Date: Thu, 3 Jun 2010 19:30:00 +0000
Subject: work on io impl for usrp-e using read/write

---
 host/lib/usrp/usrp_e/CMakeLists.txt   |   1 +
 host/lib/usrp/usrp_e/io_impl.cpp      | 137 ++++++++++++++++++++++++++++++++++
 host/lib/usrp/usrp_e/usrp_e_iface.cpp |   4 +
 host/lib/usrp/usrp_e/usrp_e_iface.hpp |   6 ++
 host/lib/usrp/usrp_e/usrp_e_impl.cpp  |  30 +-------
 host/lib/usrp/usrp_e/usrp_e_impl.hpp  |  35 ++++-----
 6 files changed, 166 insertions(+), 47 deletions(-)
 create mode 100644 host/lib/usrp/usrp_e/io_impl.cpp

(limited to 'host/lib/usrp')

diff --git a/host/lib/usrp/usrp_e/CMakeLists.txt b/host/lib/usrp/usrp_e/CMakeLists.txt
index 6035d4ff2..568fbd132 100644
--- a/host/lib/usrp/usrp_e/CMakeLists.txt
+++ b/host/lib/usrp/usrp_e/CMakeLists.txt
@@ -49,6 +49,7 @@ IF(HAVE_USRP_E_REQUIRED_HEADERS)
         ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/dboard_iface.cpp
         ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/dsp_impl.cpp
         ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/fpga-downloader.cc
+        ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/io_impl.cpp
         ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/mboard_impl.cpp
         ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_impl.cpp
         ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e/usrp_e_impl.hpp
diff --git a/host/lib/usrp/usrp_e/io_impl.cpp b/host/lib/usrp/usrp_e/io_impl.cpp
new file mode 100644
index 000000000..5bb40723e
--- /dev/null
+++ b/host/lib/usrp/usrp_e/io_impl.cpp
@@ -0,0 +1,137 @@
+//
+// 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/>.
+//
+
+#include "usrp_e_impl.hpp"
+#include "../../transport/vrt_packet_handler.hpp"
+#include <boost/bind.hpp>
+#include <fcntl.h> //read, write
+#include <linux/usrp_e.h> //transfer frame struct
+#include <stddef.h> //offsetof
+
+using namespace uhd;
+
+/***********************************************************************
+ * Data Transport (phony zero-copy with read/write)
+ **********************************************************************/
+class data_transport:
+    public transport::phony_zero_copy_recv_if,
+    public transport::phony_zero_copy_send_if
+{
+public:
+    data_transport(int fd):
+        transport::phony_zero_copy_recv_if(2048), //FIXME magic #
+        transport::phony_zero_copy_send_if(2048), //FIXME magic #
+        _fd(fd)
+    {
+        /* NOP */
+    }
+
+    size_t get_num_recv_frames(void) const{
+        return 10; //FIXME no idea!
+    }
+
+    size_t get_num_send_frames(void) const{
+        return 10; //FIXME no idea!
+    }
+
+private:
+    int _fd;
+    size_t send(const boost::asio::const_buffer &buff){
+        return write(
+            _fd,
+            boost::asio::buffer_cast<const void *>(buff),
+            boost::asio::buffer_size(buff)
+        );
+    }
+    size_t recv(const boost::asio::mutable_buffer &buff){
+        return read(
+            _fd,
+            boost::asio::buffer_cast<void *>(buff),
+            boost::asio::buffer_size(buff)
+        );
+    }
+};
+
+/***********************************************************************
+ * IO Implementation Details
+ **********************************************************************/
+struct usrp_e_impl::io_impl{
+    vrt_packet_handler::recv_state recv_state;
+    vrt_packet_handler::send_state send_state;
+    data_transport transport;
+    io_impl(int fd): transport(fd){}
+};
+
+void usrp_e_impl::io_init(void){
+    _io_impl = UHD_PIMPL_MAKE(io_impl, (_iface->get_file_descriptor()));
+}
+
+/***********************************************************************
+ * Data Send
+ **********************************************************************/
+size_t usrp_e_impl::send(
+    const boost::asio::const_buffer &buff,
+    const uhd::tx_metadata_t &metadata,
+    const io_type_t & io_type,
+    send_mode_t send_mode
+){
+    otw_type_t send_otw_type;
+    send_otw_type.width = 16;
+    send_otw_type.shift = 0;
+    send_otw_type.byteorder = otw_type_t::BO_NATIVE;
+
+    return vrt_packet_handler::send(
+        _io_impl->send_state,
+        buff,
+        metadata,
+        send_mode,
+        io_type,
+        send_otw_type, //TODO
+        64e6, //TODO
+        boost::bind(&data_transport::get_send_buff, &_io_impl->transport),
+        _max_num_samples, //TODO
+        offsetof(usrp_transfer_frame, buf)
+        //TODO probably need callback to fill in frame size
+    );
+}
+
+/***********************************************************************
+ * Data Recv
+ **********************************************************************/
+size_t usrp_e_impl::recv(
+    const boost::asio::mutable_buffer &buff,
+    uhd::rx_metadata_t &metadata,
+    const io_type_t &io_type,
+    recv_mode_t recv_mode
+){
+    otw_type_t recv_otw_type;
+    recv_otw_type.width = 16;
+    recv_otw_type.shift = 0;
+    recv_otw_type.byteorder = otw_type_t::BO_NATIVE;
+
+    return vrt_packet_handler::recv(
+        _io_impl->recv_state,
+        buff,
+        metadata,
+        recv_mode,
+        io_type,
+        recv_otw_type, //TODO
+        64e6, //TODO
+        boost::bind(&data_transport::get_recv_buff, &_io_impl->transport),
+        offsetof(usrp_transfer_frame, buf)
+    );
+}
diff --git a/host/lib/usrp/usrp_e/usrp_e_iface.cpp b/host/lib/usrp/usrp_e/usrp_e_iface.cpp
index 98d8ef478..21e91452f 100644
--- a/host/lib/usrp/usrp_e/usrp_e_iface.cpp
+++ b/host/lib/usrp/usrp_e/usrp_e_iface.cpp
@@ -29,6 +29,10 @@ using namespace uhd;
 class usrp_e_iface_impl : public usrp_e_iface{
 public:
 
+    int get_file_descriptor(void){
+        return _node_fd;
+    }
+
     /*******************************************************************
      * Structors
      ******************************************************************/
diff --git a/host/lib/usrp/usrp_e/usrp_e_iface.hpp b/host/lib/usrp/usrp_e/usrp_e_iface.hpp
index 6363a24b2..59aac43d9 100644
--- a/host/lib/usrp/usrp_e/usrp_e_iface.hpp
+++ b/host/lib/usrp/usrp_e/usrp_e_iface.hpp
@@ -49,6 +49,12 @@ public:
      */
     static sptr make(const std::string &node);
 
+    /*!
+     * Get the underlying file descriptor.
+     * \return the file descriptor
+     */
+    virtual int get_file_descriptor(void) = 0;
+
     /*!
      * Perform an ioctl call on the device node file descriptor.
      * This will throw when the internal ioctl call fails.
diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp
index 4a398e21c..f9af36887 100644
--- a/host/lib/usrp/usrp_e/usrp_e_impl.cpp
+++ b/host/lib/usrp/usrp_e/usrp_e_impl.cpp
@@ -89,6 +89,9 @@ usrp_e_impl::usrp_e_impl(const std::string &node){
     //initialize the dsps
     rx_ddc_init();
     tx_duc_init();
+
+    //init the io send/recv
+    io_init();
 }
 
 usrp_e_impl::~usrp_e_impl(void){
@@ -127,30 +130,3 @@ void usrp_e_impl::get(const wax::obj &key_, wax::obj &val){
 void usrp_e_impl::set(const wax::obj &, const wax::obj &){
     UHD_THROW_PROP_SET_ERROR();
 }
-
-/***********************************************************************
- * Device IO (TODO)
- **********************************************************************/
-size_t usrp_e_impl::send(
-    const boost::asio::const_buffer &,
-    const uhd::tx_metadata_t &,
-    const io_type_t &,
-    send_mode_t
-){
-    if (true){
-        throw std::runtime_error(str(boost::format("usrp-e send: cannot handle type \"%s\"") % ""));
-    }
-    return 0;
-}
-
-size_t usrp_e_impl::recv(
-    const boost::asio::mutable_buffer &,
-    uhd::rx_metadata_t &,
-    const io_type_t &,
-    recv_mode_t
-){
-    if (true){
-        throw std::runtime_error(str(boost::format("usrp-e recv: cannot handle type \"%s\"") % ""));
-    }
-    return 0;
-}
diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp
index a2cdbc31e..12d4c9d9e 100644
--- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp
+++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp
@@ -18,6 +18,7 @@
 #include "usrp_e_iface.hpp"
 #include "clock_ctrl.hpp"
 #include "codec_ctrl.hpp"
+#include <uhd/utils/pimpl.hpp>
 #include <uhd/usrp/usrp_e.hpp>
 #include <uhd/usrp/dboard_eeprom.hpp>
 #include <uhd/types/clock_config.hpp>
@@ -55,26 +56,11 @@ public:
         return sptr(new wax_obj_proxy(get, set));
     }
 
-    ~wax_obj_proxy(void){
-        /* NOP */
-    }
-
 private:
-    get_t _get;
-    set_t _set;
-
-    wax_obj_proxy(const get_t &get, const set_t &set){
-        _get = get;
-        _set = set;
-    };
-
-    void get(const wax::obj &key, wax::obj &val){
-        return _get(key, val);
-    }
-
-    void set(const wax::obj &key, const wax::obj &val){
-        return _set(key, val);
-    }
+    get_t _get; set_t _set;
+    wax_obj_proxy(const get_t &get, const set_t &set): _get(get), _set(set){};
+    void get(const wax::obj &key, wax::obj &val){return _get(key, val);}
+    void set(const wax::obj &key, const wax::obj &val){return _set(key, val);}
 };
 
 /*!
@@ -95,10 +81,19 @@ public:
     size_t get_max_recv_samps_per_packet(void) const{return _max_num_samples;}
 
 private:
-    static const size_t _max_num_samples = 2048/sizeof(boost::uint32_t);
+    //interface to ioctls and file descriptor
     usrp_e_iface::sptr _iface;
 
+    //FIXME fetch from ioctl?
+    static const size_t _max_num_samples = 2048/sizeof(boost::uint32_t);
+
+    //handle io stuff
+    UHD_PIMPL_DECL(io_impl) _io_impl;
+    void io_init(void);
+
+    //configuration shadows
     uhd::clock_config_t _clock_config;
+    //TODO otw type recv/send
 
     //ad9522 clock control
     clock_ctrl::sptr _clock_ctrl;
-- 
cgit v1.2.3