From 5f2c71383a2b5dd0f2f469f6ad8c4720358f2a12 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 9 Nov 2010 19:02:11 -0800 Subject: usrp-e100: renamed files and classes in usrp-e100 to e100 name --- host/lib/usrp/usrp_e100/usrp_e100_iface.cpp | 194 ++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 host/lib/usrp/usrp_e100/usrp_e100_iface.cpp (limited to 'host/lib/usrp/usrp_e100/usrp_e100_iface.cpp') diff --git a/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp b/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp new file mode 100644 index 000000000..ad623777e --- /dev/null +++ b/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp @@ -0,0 +1,194 @@ +// +// 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 . +// + +#include "usrp_e100_iface.hpp" +#include +#include //ioctl +#include //open, close +#include //ioctl structures and constants +#include +#include //mutex +#include + +using namespace uhd; + +class usrp_e100_iface_impl : public usrp_e100_iface{ +public: + + int get_file_descriptor(void){ + return _node_fd; + } + + /******************************************************************* + * Structors + ******************************************************************/ + usrp_e100_iface_impl(const std::string &node){ + //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 + )); + } + } + + ~usrp_e100_iface_impl(void){ + //close the device node file descriptor + ::close(_node_fd); + } + + /******************************************************************* + * IOCTL: provides the communication base for all other calls + ******************************************************************/ + void ioctl(int request, void *mem){ + boost::mutex::scoped_lock lock(_ctrl_mutex); + + if (::ioctl(_node_fd, request, mem) < 0){ + throw std::runtime_error(str( + boost::format("ioctl failed with request %d") % request + )); + } + } + + /******************************************************************* + * Peek and Poke + ******************************************************************/ + void poke32(boost::uint32_t addr, boost::uint32_t value){ + //load the data struct + usrp_e_ctl32 data; + data.offset = addr; + data.count = 1; + data.buf[0] = value; + + //call the ioctl + this->ioctl(USRP_E_WRITE_CTL32, &data); + } + + void poke16(boost::uint32_t addr, boost::uint16_t value){ + //load the data struct + usrp_e_ctl16 data; + data.offset = addr; + data.count = 1; + data.buf[0] = value; + + //call the ioctl + this->ioctl(USRP_E_WRITE_CTL16, &data); + } + + boost::uint32_t peek32(boost::uint32_t addr){ + //load the data struct + usrp_e_ctl32 data; + data.offset = addr; + data.count = 1; + + //call the ioctl + this->ioctl(USRP_E_READ_CTL32, &data); + + return data.buf[0]; + } + + boost::uint16_t peek16(boost::uint32_t addr){ + //load the data struct + usrp_e_ctl16 data; + data.offset = addr; + data.count = 1; + + //call the ioctl + this->ioctl(USRP_E_READ_CTL16, &data); + + return data.buf[0]; + } + + /******************************************************************* + * I2C + ******************************************************************/ + static const size_t max_i2c_data_bytes = 10; + + void write_i2c(boost::uint8_t addr, const byte_vector_t &bytes){ + //allocate some memory for this transaction + UHD_ASSERT_THROW(bytes.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(mem); + data->addr = addr; + data->len = bytes.size(); + std::copy(bytes.begin(), bytes.end(), data->data); + + //call the spi ioctl + this->ioctl(USRP_E_I2C_WRITE, data); + } + + byte_vector_t read_i2c(boost::uint8_t addr, size_t num_bytes){ + //allocate some memory for this transaction + UHD_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(mem); + data->addr = addr; + data->len = num_bytes; + + //call the spi ioctl + this->ioctl(USRP_E_I2C_READ, data); + + //unload the data + byte_vector_t bytes(data->len); + UHD_ASSERT_THROW(bytes.size() == num_bytes); + std::copy(data->data, data->data+bytes.size(), bytes.begin()); + return bytes; + } + + /******************************************************************* + * SPI + ******************************************************************/ + boost::uint32_t transact_spi( + int which_slave, + const spi_config_t &config, + boost::uint32_t bits, + size_t num_bits, + bool readback + ){ + //load data struct + usrp_e_spi data; + data.readback = (readback)? UE_SPI_TXRX : UE_SPI_TXONLY; + data.slave = which_slave; + data.length = num_bits; + data.data = bits; + + //load the flags + data.flags = 0; + data.flags |= (config.miso_edge == spi_config_t::EDGE_RISE)? UE_SPI_LATCH_RISE : UE_SPI_LATCH_FALL; + data.flags |= (config.mosi_edge == spi_config_t::EDGE_RISE)? UE_SPI_PUSH_FALL : UE_SPI_PUSH_RISE; + + //call the spi ioctl + this->ioctl(USRP_E_SPI, &data); + + //unload the data + return data.data; + } + +private: + int _node_fd; + boost::mutex _ctrl_mutex; +}; + +/*********************************************************************** + * Public Make Function + **********************************************************************/ +usrp_e100_iface::sptr usrp_e100_iface::make(const std::string &node){ + return sptr(new usrp_e100_iface_impl(node)); +} -- cgit v1.2.3 From a724f4b7262c6da6d24dccdbd64e08da61cb87fc Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 10 Nov 2010 16:48:02 -0800 Subject: usrp-e100: implemented wrapper for i2c device node + ioctls, implemented e100 eeprom map --- host/include/uhd/usrp/mboard_eeprom.hpp | 3 +- host/lib/usrp/mboard_eeprom.cpp | 77 +++++++++++++++++++++++++++ host/lib/usrp/usrp_e100/mboard_impl.cpp | 10 +++- host/lib/usrp/usrp_e100/usrp_e100_iface.cpp | 82 +++++++++++++++++++++++++++-- host/lib/usrp/usrp_e100/usrp_e100_iface.hpp | 7 +++ 5 files changed, 172 insertions(+), 7 deletions(-) (limited to 'host/lib/usrp/usrp_e100/usrp_e100_iface.cpp') 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 #include #include +#include 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 static const byte_vector_t to_bytes(const T &item){ + return byte_vector_t( + reinterpret_cast(&item), + reinterpret_cast(&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(map.device_vendor); + mb_eeprom["revision"] = boost::lexical_cast(map.revision); + mb_eeprom["content"] = boost::lexical_cast(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(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(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(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 #include #include -#include #include #include @@ -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().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 //ioctl structures and constants #include #include //mutex +#include +#include #include 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){ @@ -63,6 +129,13 @@ public: } } + /******************************************************************* + * I2C device node interface + ******************************************************************/ + i2c_iface &get_i2c_dev_iface(void){ + return _i2c_dev_iface; + } + /******************************************************************* * Peek and Poke ******************************************************************/ @@ -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 +#include #include #include #include @@ -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 */ -- cgit v1.2.3 From f2d5f0b12bd0e9a29d22a93a6aaa4565021583e4 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Thu, 11 Nov 2010 09:20:26 -0800 Subject: usrp_eXXX: Only include i2c-dev.h due to struct definition conflicts. --- host/lib/usrp/usrp_e100/usrp_e100_iface.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'host/lib/usrp/usrp_e100/usrp_e100_iface.cpp') diff --git a/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp b/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp index 40c7afabb..50ff4a8ff 100644 --- a/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp +++ b/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp @@ -23,7 +23,6 @@ #include #include //mutex #include -#include #include using namespace uhd; -- cgit v1.2.3 From 862a3f264671a133d9ff7e5b39d707d105a1dd45 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Wed, 17 Nov 2010 11:11:37 -0800 Subject: usrp e100 : Add i2c header back. --- host/lib/usrp/usrp_e100/usrp_e100_iface.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'host/lib/usrp/usrp_e100/usrp_e100_iface.cpp') diff --git a/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp b/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp index 50ff4a8ff..40c7afabb 100644 --- a/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp +++ b/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp @@ -23,6 +23,7 @@ #include #include //mutex #include +#include #include using namespace uhd; -- cgit v1.2.3