summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-03-22 13:12:03 +0000
committerJosh Blum <josh@joshknows.com>2010-03-22 13:12:03 +0000
commita31761cb0c37b61f7243836d6dd8c40cbf49efc0 (patch)
treea316d9c025fe06bf372c7c5699577ba2985bc8ae
parent6ba5135c96d81d23eafa4f0740ebbf113d8c798f (diff)
downloaduhd-a31761cb0c37b61f7243836d6dd8c40cbf49efc0.tar.gz
uhd-a31761cb0c37b61f7243836d6dd8c40cbf49efc0.tar.bz2
uhd-a31761cb0c37b61f7243836d6dd8c40cbf49efc0.zip
filled in more skeleton code, filled in dboard interface spi and i2c with ioctls, added file descriptor opening, and checking for usrp1 kernel header
-rw-r--r--host/lib/CMakeLists.txt1
-rw-r--r--host/lib/usrp/usrp1e/dboard_impl.cpp4
-rw-r--r--host/lib/usrp/usrp1e/dboard_interface.cpp60
-rw-r--r--host/lib/usrp/usrp1e/dsp_impl.cpp11
-rw-r--r--host/lib/usrp/usrp1e/mboard_impl.cpp6
-rw-r--r--host/lib/usrp/usrp1e/usrp1e_impl.cpp79
-rw-r--r--host/lib/usrp/usrp1e/usrp1e_impl.hpp48
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.hpp2
8 files changed, 172 insertions, 39 deletions
diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt
index a7dded86b..46cce729e 100644
--- a/host/lib/CMakeLists.txt
+++ b/host/lib/CMakeLists.txt
@@ -56,6 +56,7 @@ INCLUDE(CheckIncludeFiles)
SET(usrp1e_required_headers
linux/ioctl.h
linux/spi/spidev.h
+ linux/usrp1_e.h
)
CHECK_INCLUDE_FILES(
"${usrp1e_required_headers}"
diff --git a/host/lib/usrp/usrp1e/dboard_impl.cpp b/host/lib/usrp/usrp1e/dboard_impl.cpp
index 7d46366bc..a2798dce3 100644
--- a/host/lib/usrp/usrp1e/dboard_impl.cpp
+++ b/host/lib/usrp/usrp1e/dboard_impl.cpp
@@ -37,11 +37,11 @@ void usrp1e_impl::dboard_init(void){
);
//setup the dboard proxies
- _rx_dboard_proxy = wax_obj_proxy(
+ _rx_dboard_proxy = wax_obj_proxy::make(
boost::bind(&usrp1e_impl::rx_dboard_get, this, _1, _2),
boost::bind(&usrp1e_impl::rx_dboard_set, this, _1, _2)
);
- _tx_dboard_proxy = wax_obj_proxy(
+ _tx_dboard_proxy = wax_obj_proxy::make(
boost::bind(&usrp1e_impl::tx_dboard_get, this, _1, _2),
boost::bind(&usrp1e_impl::tx_dboard_set, this, _1, _2)
);
diff --git a/host/lib/usrp/usrp1e/dboard_interface.cpp b/host/lib/usrp/usrp1e/dboard_interface.cpp
index b3e06f7be..ef91014ac 100644
--- a/host/lib/usrp/usrp1e/dboard_interface.cpp
+++ b/host/lib/usrp/usrp1e/dboard_interface.cpp
@@ -16,7 +16,9 @@
//
#include <uhd/utils.hpp>
+#include <algorithm> //std::copy
#include "usrp1e_impl.hpp"
+#include <linux/usrp1_e.h>
using namespace uhd::usrp;
@@ -109,18 +111,70 @@ dboard_interface::byte_vector_t usrp1e_dboard_interface::transact_spi(
const byte_vector_t &buf,
bool readback
){
- throw std::runtime_error("not implemented");
+ //load data struct
+ usrp_e_spi data;
+ data.readback = (readback)? UE_SPI_TXRX : UE_SPI_TXONLY;
+ data.slave = (dev == SPI_RX_DEV)? UE_SPI_CTRL_RXNEG : UE_SPI_CTRL_TXNEG;
+ data.length = buf.size() * 8; //bytes to bits
+ boost::uint8_t *data_bytes = reinterpret_cast<boost::uint8_t*>(&data.data);
+
+ //load the data
+ ASSERT_THROW(buf.size() <= sizeof(data.data));
+ std::copy(buf.begin(), buf.end(), data_bytes);
+
+ //load the flags
+ data.flags = 0;
+ data.flags |= (latch == SPI_LATCH_RISE)? UE_SPI_LATCH_RISE : UE_SPI_LATCH_FALL;
+ data.flags |= (push == SPI_PUSH_RISE)? UE_SPI_PUSH_RISE : UE_SPI_PUSH_FALL;
+
+ //call the spi ioctl
+ _impl->ioctl(USRP_E_SPI, &data);
+
+ //unload the data
+ byte_vector_t ret(data.length/8); //bits to bytes
+ ASSERT_THROW(ret.size() <= sizeof(data.data));
+ std::copy(data_bytes, data_bytes+ret.size(), ret.begin());
+ return ret;
}
/***********************************************************************
* I2C
**********************************************************************/
+static const size_t max_i2c_data_bytes = 10;
+
void usrp1e_dboard_interface::write_i2c(int i2c_addr, const byte_vector_t &buf){
- throw std::runtime_error("not implemented");
+ //allocate some memory for this transaction
+ ASSERT_THROW(buf.size() <= max_i2c_data_bytes);
+ boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes];
+
+ //load the data struct
+ usrp_e_i2c &data = reinterpret_cast<usrp_e_i2c&>(mem);
+ data.addr = i2c_addr;
+ data.len = buf.size();
+ std::copy(buf.begin(), buf.end(), data.data);
+
+ //call the spi ioctl
+ _impl->ioctl(USRP_E_I2C_WRITE, &data);
}
dboard_interface::byte_vector_t usrp1e_dboard_interface::read_i2c(int i2c_addr, size_t num_bytes){
- throw std::runtime_error("not implemented");
+ //allocate some memory for this transaction
+ ASSERT_THROW(num_bytes <= max_i2c_data_bytes);
+ boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes];
+
+ //load the data struct
+ usrp_e_i2c &data = reinterpret_cast<usrp_e_i2c&>(mem);
+ data.addr = i2c_addr;
+ data.len = num_bytes;
+
+ //call the spi ioctl
+ _impl->ioctl(USRP_E_I2C_READ, &data);
+
+ //unload the data
+ byte_vector_t ret(data.len);
+ ASSERT_THROW(ret.size() == num_bytes);
+ std::copy(data.data, data.data+ret.size(), ret.begin());
+ return ret;
}
/***********************************************************************
diff --git a/host/lib/usrp/usrp1e/dsp_impl.cpp b/host/lib/usrp/usrp1e/dsp_impl.cpp
index b6076ef97..862b89184 100644
--- a/host/lib/usrp/usrp1e/dsp_impl.cpp
+++ b/host/lib/usrp/usrp1e/dsp_impl.cpp
@@ -15,6 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
+#include <boost/bind.hpp>
#include <uhd/utils.hpp>
#include "usrp1e_impl.hpp"
@@ -24,7 +25,10 @@ using namespace uhd::usrp;
* RX DDC Initialization
**********************************************************************/
void usrp1e_impl::rx_ddc_init(void){
-
+ _rx_ddc_proxy = wax_obj_proxy::make(
+ boost::bind(&usrp1e_impl::rx_ddc_get, this, _1, _2),
+ boost::bind(&usrp1e_impl::rx_ddc_set, this, _1, _2)
+ );
}
/***********************************************************************
@@ -45,7 +49,10 @@ void usrp1e_impl::rx_ddc_set(const wax::obj &, const wax::obj &){
* TX DUC Initialization
**********************************************************************/
void usrp1e_impl::tx_duc_init(void){
-
+ _tx_duc_proxy = wax_obj_proxy::make(
+ boost::bind(&usrp1e_impl::tx_duc_get, this, _1, _2),
+ boost::bind(&usrp1e_impl::tx_duc_set, this, _1, _2)
+ );
}
/***********************************************************************
diff --git a/host/lib/usrp/usrp1e/mboard_impl.cpp b/host/lib/usrp/usrp1e/mboard_impl.cpp
index c79ed1820..b480f7616 100644
--- a/host/lib/usrp/usrp1e/mboard_impl.cpp
+++ b/host/lib/usrp/usrp1e/mboard_impl.cpp
@@ -15,6 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
+#include <boost/bind.hpp>
#include <uhd/utils.hpp>
#include "usrp1e_impl.hpp"
@@ -24,7 +25,10 @@ using namespace uhd::usrp;
* Mboard Initialization
**********************************************************************/
void usrp1e_impl::mboard_init(void){
-
+ _mboard_proxy = wax_obj_proxy::make(
+ boost::bind(&usrp1e_impl::mboard_get, this, _1, _2),
+ boost::bind(&usrp1e_impl::mboard_set, this, _1, _2)
+ );
}
/***********************************************************************
diff --git a/host/lib/usrp/usrp1e/usrp1e_impl.cpp b/host/lib/usrp/usrp1e/usrp1e_impl.cpp
index 14c4b7278..d3b0264a7 100644
--- a/host/lib/usrp/usrp1e/usrp1e_impl.cpp
+++ b/host/lib/usrp/usrp1e/usrp1e_impl.cpp
@@ -19,9 +19,12 @@
#include <boost/format.hpp>
#include <boost/filesystem.hpp>
#include "usrp1e_impl.hpp"
+#include <fcntl.h> //open
+#include <sys/ioctl.h> //ioctl
using namespace uhd;
using namespace uhd::usrp;
+namespace fs = boost::filesystem;
STATIC_BLOCK(register_usrp1e_device){
device::register_device(&usrp1e::discover, &usrp1e::make);
@@ -30,8 +33,8 @@ STATIC_BLOCK(register_usrp1e_device){
/***********************************************************************
* Helper Functions
**********************************************************************/
-static bool file_exists(const std::string &file_path){
- return boost::filesystem::exists(file_path);
+static std::string abs_path(const std::string &file_path){
+ return fs::system_complete(fs::path(file_path)).file_string();
}
/***********************************************************************
@@ -42,10 +45,10 @@ device_addrs_t usrp1e::discover(const device_addr_t &device_addr){
//if a node was provided, use it and only it
if (device_addr.has_key("node")){
- if (not file_exists(device_addr["node"])) return usrp1e_addrs;
+ if (not fs::exists(device_addr["node"])) return usrp1e_addrs;
device_addr_t new_addr;
new_addr["name"] = "USRP1E";
- new_addr["node"] = device_addr["node"];
+ new_addr["node"] = abs_path(device_addr["node"]);
usrp1e_addrs.push_back(new_addr);
}
@@ -53,10 +56,10 @@ device_addrs_t usrp1e::discover(const device_addr_t &device_addr){
else{
for(size_t i = 0; i < 5; i++){
std::string node = str(boost::format("/dev/usrp1_e%d") % i);
- if (not file_exists(node)) continue;
+ if (not fs::exists(node)) continue;
device_addr_t new_addr;
new_addr["name"] = "USRP1E";
- new_addr["node"] = node;
+ new_addr["node"] = abs_path(node);
usrp1e_addrs.push_back(new_addr);
}
}
@@ -67,14 +70,23 @@ device_addrs_t usrp1e::discover(const device_addr_t &device_addr){
/***********************************************************************
* Make
**********************************************************************/
-device::sptr usrp1e::make(const device_addr_t &){
- throw std::runtime_error("not implemented yet");
+device::sptr usrp1e::make(const device_addr_t &device_addr){
+ std::string node = device_addr["node"];
+ int node_fd = open(node.c_str(), 0);
+ if (node_fd < 0){
+ throw std::runtime_error(str(
+ boost::format("Failed to open %s") % node
+ ));
+ }
+ return sptr(new usrp1e_impl(node_fd));
}
/***********************************************************************
* Structors
**********************************************************************/
-usrp1e_impl::usrp1e_impl(void){
+usrp1e_impl::usrp1e_impl(int node_fd){
+ _node_fd = node_fd;
+
//initialize the mboard
mboard_init();
@@ -91,15 +103,58 @@ usrp1e_impl::~usrp1e_impl(void){
}
/***********************************************************************
+ * Misc Methods
+ **********************************************************************/
+void usrp1e_impl::ioctl(int request, void *mem){
+ if (::ioctl(_node_fd, request, mem) < 0){
+ throw std::runtime_error(str(
+ boost::format("ioctl failed with request %d") % request
+ ));
+ }
+}
+
+/***********************************************************************
* Device Get
**********************************************************************/
-void usrp1e_impl::get(const wax::obj &, wax::obj &){
-
+void usrp1e_impl::get(const wax::obj &key_, wax::obj &val){
+ wax::obj key; std::string name;
+ boost::tie(key, name) = extract_named_prop(key_);
+
+ //handle the get request conditioned on the key
+ switch(key.as<device_prop_t>()){
+ case DEVICE_PROP_NAME:
+ val = std::string("usrp1e device");
+ return;
+
+ case DEVICE_PROP_MBOARD:
+ ASSERT_THROW(name == "");
+ val = _mboard_proxy->get_link();
+ return;
+
+ case DEVICE_PROP_MBOARD_NAMES:
+ val = prop_names_t(1, ""); //vector of size 1 with empty string
+ return;
+
+ case DEVICE_PROP_MAX_RX_SAMPLES:
+ val = size_t(0); //TODO
+ return;
+
+ case DEVICE_PROP_MAX_TX_SAMPLES:
+ val = size_t(0); //TODO
+ return;
+
+ }
}
/***********************************************************************
* Device Set
**********************************************************************/
void usrp1e_impl::set(const wax::obj &, const wax::obj &){
-
+ throw std::runtime_error("Cannot set in usrp1e device");
}
+
+/***********************************************************************
+ * Device IO (TODO)
+ **********************************************************************/
+size_t usrp1e_impl::send(const boost::asio::const_buffer &, const uhd::tx_metadata_t &, const std::string &){return 0;}
+size_t usrp1e_impl::recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const std::string &){return 0;}
diff --git a/host/lib/usrp/usrp1e/usrp1e_impl.hpp b/host/lib/usrp/usrp1e/usrp1e_impl.hpp
index 3b2fcdd57..7a09254ec 100644
--- a/host/lib/usrp/usrp1e/usrp1e_impl.hpp
+++ b/host/lib/usrp/usrp1e/usrp1e_impl.hpp
@@ -40,20 +40,25 @@ class wax_obj_proxy : public wax::obj{
public:
typedef boost::function<void(const wax::obj &, wax::obj &)> get_t;
typedef boost::function<void(const wax::obj &, const wax::obj &)> set_t;
+ typedef boost::shared_ptr<wax_obj_proxy> sptr;
- wax_obj_proxy(void){
+ static sptr make(const get_t &get, const set_t &set){
+ 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;
};
- ~wax_obj_proxy(void){
- /* NOP */
- }
-
void get(const wax::obj &key, wax::obj &val){
return _get(key, val);
}
@@ -61,10 +66,6 @@ public:
void set(const wax::obj &key, const wax::obj &val){
return _set(key, val);
}
-
-private:
- get_t _get;
- set_t _set;
};
/*!
@@ -74,12 +75,25 @@ private:
*/
class usrp1e_impl : public uhd::device{
public:
- typedef boost::shared_ptr<usrp1e_impl> sptr;
-
- usrp1e_impl(void);
+ //structors
+ usrp1e_impl(int node_fd);
~usrp1e_impl(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 &);
+
+ /*!
+ * Perform an ioctl call on the device node file descriptor.
+ * This will throw when the internal ioctl call fails.
+ * \param request the control word
+ * \param mem pointer to some memory
+ */
+ void ioctl(int request, void *mem);
+
private:
+ int _node_fd;
+
//device functions and settings
void get(const wax::obj &, wax::obj &);
void set(const wax::obj &, const wax::obj &);
@@ -88,7 +102,7 @@ private:
void mboard_init(void);
void mboard_get(const wax::obj &, wax::obj &);
void mboard_set(const wax::obj &, const wax::obj &);
- wax_obj_proxy _mboard_proxy;
+ wax_obj_proxy::sptr _mboard_proxy;
//xx dboard functions and settings
void dboard_init(void);
@@ -97,24 +111,24 @@ private:
//rx dboard functions and settings
void rx_dboard_get(const wax::obj &, wax::obj &);
void rx_dboard_set(const wax::obj &, const wax::obj &);
- wax_obj_proxy _rx_dboard_proxy;
+ wax_obj_proxy::sptr _rx_dboard_proxy;
//tx dboard functions and settings
void tx_dboard_get(const wax::obj &, wax::obj &);
void tx_dboard_set(const wax::obj &, const wax::obj &);
- wax_obj_proxy _tx_dboard_proxy;
+ wax_obj_proxy::sptr _tx_dboard_proxy;
//rx ddc functions and settings
void rx_ddc_init(void);
void rx_ddc_get(const wax::obj &, wax::obj &);
void rx_ddc_set(const wax::obj &, const wax::obj &);
- wax_obj_proxy _rx_ddc_proxy;
+ wax_obj_proxy::sptr _rx_ddc_proxy;
//tx duc functions and settings
void tx_duc_init(void);
void tx_duc_get(const wax::obj &, wax::obj &);
void tx_duc_set(const wax::obj &, const wax::obj &);
- wax_obj_proxy _tx_duc_proxy;
+ wax_obj_proxy::sptr _tx_duc_proxy;
};
#endif /* INCLUDED_USRP1E_IMPL_HPP */
diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp
index 70420fd49..55ac0b192 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.hpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.hpp
@@ -86,8 +86,6 @@ private:
*/
class usrp2_impl : public uhd::device{
public:
- typedef boost::shared_ptr<usrp2_impl> sptr;
-
/*!
* Create a new usrp2 impl base.
* \param ctrl_transport the udp transport for control