summaryrefslogtreecommitdiffstats
path: root/host
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-11-10 16:48:02 -0800
committerJosh Blum <josh@joshknows.com>2010-11-10 16:48:02 -0800
commita724f4b7262c6da6d24dccdbd64e08da61cb87fc (patch)
tree6141d1215d36fc94d1deef0ec26d9ef532ea2e30 /host
parent123de6dad521ca3dbc44a5d9fc70ff754f1196e3 (diff)
downloaduhd-a724f4b7262c6da6d24dccdbd64e08da61cb87fc.tar.gz
uhd-a724f4b7262c6da6d24dccdbd64e08da61cb87fc.tar.bz2
uhd-a724f4b7262c6da6d24dccdbd64e08da61cb87fc.zip
usrp-e100: implemented wrapper for i2c device node + ioctls, implemented e100 eeprom map
Diffstat (limited to 'host')
-rw-r--r--host/include/uhd/usrp/mboard_eeprom.hpp3
-rw-r--r--host/lib/usrp/mboard_eeprom.cpp77
-rw-r--r--host/lib/usrp/usrp_e100/mboard_impl.cpp10
-rw-r--r--host/lib/usrp/usrp_e100/usrp_e100_iface.cpp82
-rw-r--r--host/lib/usrp/usrp_e100/usrp_e100_iface.hpp7
5 files changed, 172 insertions, 7 deletions
diff --git a/host/include/uhd/usrp/mboard_eeprom.hpp b/host/include/uhd/usrp/mboard_eeprom.hpp
index 530b177be..52363b95c 100644
--- a/host/include/uhd/usrp/mboard_eeprom.hpp
+++ b/host/include/uhd/usrp/mboard_eeprom.hpp
@@ -37,7 +37,8 @@ namespace uhd{ namespace usrp{
//! Possible EEPROM maps types
enum map_type{
MAP_N100,
- MAP_B000
+ MAP_B000,
+ MAP_E100
};
//! Make a new empty mboard eeprom
diff --git a/host/lib/usrp/mboard_eeprom.cpp b/host/lib/usrp/mboard_eeprom.cpp
index 661030aa7..444057ad9 100644
--- a/host/lib/usrp/mboard_eeprom.cpp
+++ b/host/lib/usrp/mboard_eeprom.cpp
@@ -22,6 +22,7 @@
#include <boost/assign/list_of.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/foreach.hpp>
+#include <cstddef>
using namespace uhd;
using namespace uhd::usrp;
@@ -171,6 +172,80 @@ static void store_b000(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){
string_to_bytes(mb_eeprom["name"], NAME_MAX_LEN)
);
}
+/***********************************************************************
+ * Implementation of E100 load/store
+ **********************************************************************/
+static const boost::uint8_t E100_EEPROM_ADDR = 0x51;
+
+struct e100_eeprom_map{
+ unsigned int device_vendor;
+ unsigned char revision;
+ unsigned char content;
+ unsigned char fab_revision[8];
+ unsigned char env_var[16];
+ unsigned char env_setting[64];
+ unsigned char serial[10];
+ unsigned char name[NAME_MAX_LEN];
+};
+
+template <typename T> static const byte_vector_t to_bytes(const T &item){
+ return byte_vector_t(
+ reinterpret_cast<const byte_vector_t::value_type *>(&item),
+ reinterpret_cast<const byte_vector_t::value_type *>(&item)+sizeof(item)
+ );
+}
+
+static void load_e100(mboard_eeprom_t &mb_eeprom, i2c_iface &iface){
+ const size_t num_bytes = offsetof(e100_eeprom_map, fab_revision);
+ byte_vector_t map_bytes = iface.read_eeprom(E100_EEPROM_ADDR, 0, num_bytes);
+ e100_eeprom_map map; std::memcpy(&map, &map_bytes[0], map_bytes.size());
+
+ mb_eeprom["device_vendor"] = boost::lexical_cast<std::string>(map.device_vendor);
+ mb_eeprom["revision"] = boost::lexical_cast<std::string>(map.revision);
+ mb_eeprom["content"] = boost::lexical_cast<std::string>(map.content);
+
+ #define load_e100_string_xx(key) mb_eeprom[#key] = bytes_to_string(iface.read_eeprom( \
+ E100_EEPROM_ADDR, offsetof(e100_eeprom_map, key), sizeof(e100_eeprom_map::key) \
+ ));
+
+ load_e100_string_xx(fab_revision);
+ load_e100_string_xx(env_var);
+ load_e100_string_xx(env_setting);
+ load_e100_string_xx(serial);
+ load_e100_string_xx(fab_revision);
+ load_e100_string_xx(name);
+}
+
+static void store_e100(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){
+
+ if (mb_eeprom.has_key("device_vendor")) iface.write_eeprom(
+ E100_EEPROM_ADDR, offsetof(e100_eeprom_map, device_vendor),
+ to_bytes(boost::lexical_cast<unsigned int>(mb_eeprom["device_vendor"]))
+ );
+
+ if (mb_eeprom.has_key("revision")) iface.write_eeprom(
+ E100_EEPROM_ADDR, offsetof(e100_eeprom_map, revision),
+ to_bytes(boost::lexical_cast<unsigned char>(mb_eeprom["revision"]))
+ );
+
+ if (mb_eeprom.has_key("content")) iface.write_eeprom(
+ E100_EEPROM_ADDR, offsetof(e100_eeprom_map, content),
+ to_bytes(boost::lexical_cast<unsigned char>(mb_eeprom["content"]))
+ );
+
+ #define store_e100_string_xx(key) if (mb_eeprom.has_key(#key)) iface.write_eeprom( \
+ E100_EEPROM_ADDR, offsetof(e100_eeprom_map, key), \
+ string_to_bytes(mb_eeprom[#key], sizeof(e100_eeprom_map::key)) \
+ );
+
+ store_e100_string_xx(fab_revision);
+ store_e100_string_xx(env_var);
+ store_e100_string_xx(env_setting);
+ store_e100_string_xx(serial);
+ store_e100_string_xx(fab_revision);
+ store_e100_string_xx(name);
+
+}
/***********************************************************************
* Implementation of mboard eeprom
@@ -183,6 +258,7 @@ mboard_eeprom_t::mboard_eeprom_t(i2c_iface &iface, map_type map){
switch(map){
case MAP_N100: load_n100(*this, iface); break;
case MAP_B000: load_b000(*this, iface); break;
+ case MAP_E100: load_e100(*this, iface); break;
}
}
@@ -190,5 +266,6 @@ void mboard_eeprom_t::commit(i2c_iface &iface, map_type map){
switch(map){
case MAP_N100: store_n100(*this, iface); break;
case MAP_B000: store_b000(*this, iface); break;
+ case MAP_E100: store_e100(*this, iface); break;
}
}
diff --git a/host/lib/usrp/usrp_e100/mboard_impl.cpp b/host/lib/usrp/usrp_e100/mboard_impl.cpp
index e45d7c5a0..9c6317b94 100644
--- a/host/lib/usrp/usrp_e100/mboard_impl.cpp
+++ b/host/lib/usrp/usrp_e100/mboard_impl.cpp
@@ -21,7 +21,6 @@
#include <uhd/usrp/misc_utils.hpp>
#include <uhd/utils/assert.hpp>
#include <uhd/usrp/mboard_props.hpp>
-#include <uhd/usrp/mboard_eeprom.hpp>
#include <boost/bind.hpp>
#include <iostream>
@@ -109,7 +108,7 @@ void usrp_e100_impl::mboard_get(const wax::obj &key_, wax::obj &val){
return;
case MBOARD_PROP_EEPROM_MAP:
- val = mboard_eeprom_t();
+ val = _iface->mb_eeprom;
return;
default: UHD_THROW_PROP_GET_ERROR();
@@ -159,6 +158,13 @@ void usrp_e100_impl::mboard_set(const wax::obj &key, const wax::obj &val){
));
return;
+ case MBOARD_PROP_EEPROM_MAP:
+ // Step1: commit the map, writing only those values set.
+ // Step2: readback the entire eeprom map into the iface.
+ val.as<mboard_eeprom_t>().commit(_iface->get_i2c_dev_iface(), mboard_eeprom_t::MAP_E100);
+ _iface->mb_eeprom = mboard_eeprom_t(_iface->get_i2c_dev_iface(), mboard_eeprom_t::MAP_E100);
+ return;
+
default: UHD_THROW_PROP_SET_ERROR();
}
}
diff --git a/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp b/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp
index ad623777e..40c7afabb 100644
--- a/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp
+++ b/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp
@@ -22,10 +22,74 @@
#include <linux/usrp_e.h> //ioctl structures and constants
#include <boost/format.hpp>
#include <boost/thread.hpp> //mutex
+#include <linux/i2c-dev.h>
+#include <linux/i2c.h>
#include <stdexcept>
using namespace uhd;
+using namespace uhd::usrp;
+/***********************************************************************
+ * I2C device node implementation wrapper
+ **********************************************************************/
+class i2c_dev_iface : public i2c_iface{
+public:
+ i2c_dev_iface(const std::string &node){
+ if ((_node_fd = ::open(node.c_str(), O_RDWR)) < 0){
+ throw std::runtime_error("Failed to open " + node);
+ }
+ }
+
+ ~i2c_dev_iface(void){
+ ::close(_node_fd);
+ }
+
+ void write_i2c(boost::uint8_t addr, const byte_vector_t &bytes){
+ byte_vector_t rw_bytes(bytes);
+
+ //setup the message
+ i2c_msg msg;
+ msg.addr = addr;
+ msg.flags = 0;
+ msg.len = bytes.size();
+ msg.buf = &rw_bytes.front();
+
+ //setup the data
+ i2c_rdwr_ioctl_data data;
+ data.msgs = &msg;
+ data.nmsgs = 1;
+
+ //call the ioctl
+ UHD_ASSERT_THROW(::ioctl(_node_fd, I2C_RDWR, &data) >= 0);
+ }
+
+ byte_vector_t read_i2c(boost::uint8_t addr, size_t num_bytes){
+ byte_vector_t bytes(num_bytes);
+
+ //setup the message
+ i2c_msg msg;
+ msg.addr = addr;
+ msg.flags = I2C_M_RD;
+ msg.len = bytes.size();
+ msg.buf = &bytes.front();
+
+ //setup the data
+ i2c_rdwr_ioctl_data data;
+ data.msgs = &msg;
+ data.nmsgs = 1;
+
+ //call the ioctl
+ UHD_ASSERT_THROW(::ioctl(_node_fd, I2C_RDWR, &data) >= 0);
+
+ return bytes;
+ }
+
+private: int _node_fd;
+};
+
+/***********************************************************************
+ * USRP-E100 interface implementation
+ **********************************************************************/
class usrp_e100_iface_impl : public usrp_e100_iface{
public:
@@ -36,13 +100,15 @@ public:
/*******************************************************************
* Structors
******************************************************************/
- usrp_e100_iface_impl(const std::string &node){
+ usrp_e100_iface_impl(const std::string &node):
+ _i2c_dev_iface(i2c_dev_iface("/dev/i2c-3"))
+ {
//open the device node and check file descriptor
if ((_node_fd = ::open(node.c_str(), O_RDWR)) < 0){
- throw std::runtime_error(str(
- boost::format("Failed to open %s") % node
- ));
+ throw std::runtime_error("Failed to open " + node);
}
+
+ mb_eeprom = mboard_eeprom_t(get_i2c_dev_iface(), mboard_eeprom_t::MAP_E100);
}
~usrp_e100_iface_impl(void){
@@ -64,6 +130,13 @@ public:
}
/*******************************************************************
+ * I2C device node interface
+ ******************************************************************/
+ i2c_iface &get_i2c_dev_iface(void){
+ return _i2c_dev_iface;
+ }
+
+ /*******************************************************************
* Peek and Poke
******************************************************************/
void poke32(boost::uint32_t addr, boost::uint32_t value){
@@ -183,6 +256,7 @@ public:
private:
int _node_fd;
+ i2c_dev_iface _i2c_dev_iface;
boost::mutex _ctrl_mutex;
};
diff --git a/host/lib/usrp/usrp_e100/usrp_e100_iface.hpp b/host/lib/usrp/usrp_e100/usrp_e100_iface.hpp
index b52209a42..12283fb52 100644
--- a/host/lib/usrp/usrp_e100/usrp_e100_iface.hpp
+++ b/host/lib/usrp/usrp_e100/usrp_e100_iface.hpp
@@ -19,6 +19,7 @@
#define INCLUDED_USRP_E100_IFACE_HPP
#include <uhd/transport/udp_simple.hpp>
+#include <uhd/usrp/mboard_eeprom.hpp>
#include <uhd/types/serial.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/utility.hpp>
@@ -63,6 +64,9 @@ public:
*/
virtual void ioctl(int request, void *mem) = 0;
+ //! Get the I2C interface for the I2C device node
+ virtual uhd::i2c_iface &get_i2c_dev_iface(void) = 0;
+
/*!
* Write a register (32 bits)
* \param addr the address
@@ -107,6 +111,9 @@ public:
size_t num_bits,
bool readback
) = 0;
+
+ //motherboard eeprom map structure
+ uhd::usrp::mboard_eeprom_t mb_eeprom;
};
#endif /* INCLUDED_USRP_E100_IFACE_HPP */