diff options
Diffstat (limited to 'host/lib/usrp/e100')
-rw-r--r-- | host/lib/usrp/e100/CMakeLists.txt | 1 | ||||
-rw-r--r-- | host/lib/usrp/e100/e100_impl.cpp | 14 | ||||
-rw-r--r-- | host/lib/usrp/e100/e100_impl.hpp | 2 | ||||
-rw-r--r-- | host/lib/usrp/e100/mb_eeprom.cpp | 103 |
4 files changed, 111 insertions, 9 deletions
diff --git a/host/lib/usrp/e100/CMakeLists.txt b/host/lib/usrp/e100/CMakeLists.txt index da77b85dc..5bf7206d0 100644 --- a/host/lib/usrp/e100/CMakeLists.txt +++ b/host/lib/usrp/e100/CMakeLists.txt @@ -34,5 +34,6 @@ IF(ENABLE_E100) ${CMAKE_CURRENT_SOURCE_DIR}/e100_mmap_zero_copy.cpp ${CMAKE_CURRENT_SOURCE_DIR}/fpga_downloader.cpp ${CMAKE_CURRENT_SOURCE_DIR}/io_impl.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mb_eeprom.cpp ) ENDIF(ENABLE_E100) diff --git a/host/lib/usrp/e100/e100_impl.cpp b/host/lib/usrp/e100/e100_impl.cpp index ddb21fc35..7ee9dccbd 100644 --- a/host/lib/usrp/e100/e100_impl.cpp +++ b/host/lib/usrp/e100/e100_impl.cpp @@ -70,7 +70,8 @@ device_addrs_t e100_find(const device_addr_t &hint){ new_addr["node"] = fs::system_complete(fs::path(hint["node"])).string(); try{ i2c_iface::sptr i2c_iface = e100_ctrl::make_dev_i2c_iface(E100_I2C_DEV_NODE); - const mboard_eeprom_t mb_eeprom(*i2c_iface, E100_EEPROM_MAP_KEY); + const mboard_eeprom_t mb_eeprom = get_mb_eeprom(i2c_iface); + new_addr["name"] = mb_eeprom["name"]; new_addr["serial"] = mb_eeprom["serial"]; } @@ -108,7 +109,7 @@ static const uhd::dict<std::string, std::string> model_to_fpga_file_name = boost std::string get_default_e1x0_fpga_image(const uhd::device_addr_t &device_addr){ //read the eeprom so we can determine the hardware uhd::i2c_iface::sptr dev_i2c_iface = e100_ctrl::make_dev_i2c_iface(E100_I2C_DEV_NODE); - const mboard_eeprom_t mb_eeprom(*dev_i2c_iface, E100_EEPROM_MAP_KEY); + const mboard_eeprom_t mb_eeprom = e100_impl::get_mb_eeprom(dev_i2c_iface); //determine the model string for this device const std::string model = device_addr.get("model", mb_eeprom.get("model", "")); @@ -132,8 +133,9 @@ e100_impl::e100_impl(const uhd::device_addr_t &device_addr){ _ignore_cal_file = device_addr.has_key("ignore-cal-file"); _dev_i2c_iface = e100_ctrl::make_dev_i2c_iface(E100_I2C_DEV_NODE); - const mboard_eeprom_t mb_eeprom(*_dev_i2c_iface, E100_EEPROM_MAP_KEY); - const std::string default_fpga_file_name = get_default_e1x0_fpga_image(device_addr); + const mboard_eeprom_t mb_eeprom = get_mb_eeprom(_dev_i2c_iface); + const std::string default_fpga_file_name = + get_default_e1x0_fpga_image(device_addr); const std::string model = device_addr["model"]; std::string e100_fpga_image; try{ @@ -496,10 +498,6 @@ double e100_impl::update_rx_codec_gain(const double gain){ return _codec_ctrl->get_rx_pga_gain('A'); } -void e100_impl::set_mb_eeprom(const uhd::usrp::mboard_eeprom_t &mb_eeprom){ - mb_eeprom.commit(*_dev_i2c_iface, E100_EEPROM_MAP_KEY); -} - void e100_impl::set_db_eeprom(const std::string &type, const uhd::usrp::dboard_eeprom_t &db_eeprom){ if (type == "rx") db_eeprom.store(*_fpga_i2c_ctrl, I2C_ADDR_RX_DB); if (type == "tx") db_eeprom.store(*_fpga_i2c_ctrl, I2C_ADDR_TX_DB); diff --git a/host/lib/usrp/e100/e100_impl.hpp b/host/lib/usrp/e100/e100_impl.hpp index 5f8277dda..04278d757 100644 --- a/host/lib/usrp/e100/e100_impl.hpp +++ b/host/lib/usrp/e100/e100_impl.hpp @@ -55,7 +55,6 @@ static const uint32_t E100_RX_SID_BASE = 30; static const uint32_t E100_TX_ASYNC_SID = 10; static const uint32_t E100_CTRL_MSG_SID = 20; static const double E100_DEFAULT_CLOCK_RATE = 64e6; -static const std::string E100_EEPROM_MAP_KEY = "E100"; //! load an fpga image from a bin file into the usrp-e fpga extern void e100_load_fpga(const std::string &bin_file); @@ -117,6 +116,7 @@ private: std::vector<boost::weak_ptr<uhd::tx_streamer> > _tx_streamers; double update_rx_codec_gain(const double); //sets A and B at once + uhd::usrp::mboard_eeprom_t get_mb_eeprom(); void set_mb_eeprom(const uhd::usrp::mboard_eeprom_t &); void set_db_eeprom(const std::string &, const uhd::usrp::dboard_eeprom_t &); void update_tick_rate(const double rate); diff --git a/host/lib/usrp/e100/mb_eeprom.cpp b/host/lib/usrp/e100/mb_eeprom.cpp new file mode 100644 index 000000000..926688d41 --- /dev/null +++ b/host/lib/usrp/e100/mb_eeprom.cpp @@ -0,0 +1,103 @@ +// +// Copyright 2017 Ettus Research (National Instruments Corp.) +// +// SPDX-License-Identifier: GPL-3.0 +// + +#include "e100_impl.hpp" +#include "eeprom_utils.hpp" +#include <uhd/usrp/mboard_eeprom.hpp> + +namespace { + + const uint8_t E100_EEPROM_ADDR = 0x51; + + struct e100_eeprom_map{ + uint16_t vendor; + uint16_t device; + unsigned char revision; + unsigned char content; + unsigned char model[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) + ); + } +} + +using namespace uhd; +using uhd::usrp::mboard_eeprom_t; + +mboard_eeprom_t get_mb_eeprom(uhd::i2c_iface::sptr i2c) +{ + auto &iface = i2c; + uhd::usrp::mboard_eeprom_t mb_eeprom; + +#define sizeof_member(struct_name, member_name) \ + sizeof(reinterpret_cast<struct_name*>(0)->member_name) + + const size_t num_bytes = offsetof(e100_eeprom_map, model); + 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["vendor"] = std::to_string(uhd::ntohx(map.vendor)); + mb_eeprom["device"] = std::to_string(uhd::ntohx(map.device)); + mb_eeprom["revision"] = std::to_string(unsigned(map.revision)); + mb_eeprom["content"] = std::to_string(unsigned(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_member(e100_eeprom_map, key) \ + )); + + load_e100_string_xx(model); + load_e100_string_xx(env_var); + load_e100_string_xx(env_setting); + load_e100_string_xx(serial); + load_e100_string_xx(name); + + return mb_eeprom; +} + + +void e100_impl::set_mb_eeprom(const mboard_eeprom_t &mb_eeprom) +{ + auto &iface = _dev_i2c_iface; + + if (mb_eeprom.has_key("vendor")) iface->write_eeprom( + E100_EEPROM_ADDR, offsetof(e100_eeprom_map, vendor), + to_bytes(uhd::htonx(boost::lexical_cast<uint16_t>(mb_eeprom["vendor"]))) + ); + + if (mb_eeprom.has_key("device")) iface->write_eeprom( + E100_EEPROM_ADDR, offsetof(e100_eeprom_map, device), + to_bytes(uhd::htonx(boost::lexical_cast<uint16_t>(mb_eeprom["device"]))) + ); + + if (mb_eeprom.has_key("revision")) iface->write_eeprom( + E100_EEPROM_ADDR, offsetof(e100_eeprom_map, revision), + byte_vector_t(1, boost::lexical_cast<unsigned>(mb_eeprom["revision"])) + ); + + if (mb_eeprom.has_key("content")) iface->write_eeprom( + E100_EEPROM_ADDR, offsetof(e100_eeprom_map, content), + byte_vector_t(1, boost::lexical_cast<unsigned>(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_member(e100_eeprom_map, key)) \ + ); + + store_e100_string_xx(model); + store_e100_string_xx(env_var); + store_e100_string_xx(env_setting); + store_e100_string_xx(serial); + store_e100_string_xx(name); +} |