diff options
| -rw-r--r-- | host/include/uhd/usrp/mboard_eeprom.hpp | 3 | ||||
| -rw-r--r-- | host/lib/usrp/mboard_eeprom.cpp | 77 | ||||
| -rw-r--r-- | host/lib/usrp/usrp_e100/mboard_impl.cpp | 10 | ||||
| -rw-r--r-- | host/lib/usrp/usrp_e100/usrp_e100_iface.cpp | 82 | ||||
| -rw-r--r-- | host/lib/usrp/usrp_e100/usrp_e100_iface.hpp | 7 | 
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 */ | 
