aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/e300
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp/e300')
-rw-r--r--host/lib/usrp/e300/CMakeLists.txt51
-rw-r--r--host/lib/usrp/e300/e300_common.cpp98
-rw-r--r--host/lib/usrp/e300/e300_common.hpp21
-rw-r--r--host/lib/usrp/e300/e300_defaults.hpp74
-rw-r--r--host/lib/usrp/e300/e300_eeprom_manager.cpp241
-rw-r--r--host/lib/usrp/e300/e300_eeprom_manager.hpp122
-rw-r--r--host/lib/usrp/e300/e300_fifo_config.cpp437
-rw-r--r--host/lib/usrp/e300/e300_fifo_config.hpp42
-rw-r--r--host/lib/usrp/e300/e300_fpga_defs.hpp19
-rw-r--r--host/lib/usrp/e300/e300_global_regs.cpp121
-rw-r--r--host/lib/usrp/e300/e300_global_regs.hpp71
-rw-r--r--host/lib/usrp/e300/e300_i2c.cpp400
-rw-r--r--host/lib/usrp/e300/e300_i2c.hpp68
-rw-r--r--host/lib/usrp/e300/e300_impl.cpp749
-rw-r--r--host/lib/usrp/e300/e300_impl.hpp195
-rw-r--r--host/lib/usrp/e300/e300_io_impl.cpp29
-rw-r--r--host/lib/usrp/e300/e300_network.cpp655
-rw-r--r--host/lib/usrp/e300/e300_network.hpp33
-rw-r--r--host/lib/usrp/e300/e300_regs.hpp25
-rw-r--r--host/lib/usrp/e300/e300_remote_codec_ctrl.cpp285
-rw-r--r--host/lib/usrp/e300/e300_remote_codec_ctrl.hpp64
-rw-r--r--host/lib/usrp/e300/e300_sensor_manager.cpp207
-rw-r--r--host/lib/usrp/e300/e300_sensor_manager.hpp68
-rw-r--r--host/lib/usrp/e300/e300_spi.cpp119
-rw-r--r--host/lib/usrp/e300/e300_spi.hpp24
-rw-r--r--host/lib/usrp/e300/e300_sysfs_hooks.cpp114
-rw-r--r--host/lib/usrp/e300/e3xx_radio_ctrl_impl.cpp770
-rw-r--r--host/lib/usrp/e300/e3xx_radio_ctrl_impl.hpp149
28 files changed, 0 insertions, 5251 deletions
diff --git a/host/lib/usrp/e300/CMakeLists.txt b/host/lib/usrp/e300/CMakeLists.txt
deleted file mode 100644
index 9821fe34a..000000000
--- a/host/lib/usrp/e300/CMakeLists.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-#
-# Copyright 2013-2015 Ettus Research LLC
-# Copyright 2018 Ettus Research, a National Instruments Company
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-#
-
-########################################################################
-# This file included, use CMake directory variables
-########################################################################
-
-########################################################################
-# Conditionally configure the USRP-E300 support
-########################################################################
-find_package(UDev)
-
-if(ENABLE_E300)
- list(APPEND E300_SOURCES
- ${CMAKE_CURRENT_SOURCE_DIR}/e300_impl.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/e300_io_impl.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/e300_fifo_config.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/e300_sysfs_hooks.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/e300_network.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/e300_global_regs.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/e300_spi.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/e300_sensor_manager.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/e300_i2c.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/e300_eeprom_manager.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/e300_common.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/e300_remote_codec_ctrl.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/e3xx_radio_ctrl_impl.cpp
- )
- LIBUHD_APPEND_SOURCES(${E300_SOURCES})
- if(UDEV_FOUND AND NOT E300_FORCE_NETWORK)
- include_directories(${UDEV_INCLUDE_DIR})
- LIBUHD_APPEND_LIBS(${UDEV_LIBS})
- set_source_files_properties(
- ${E300_SOURCES}
- PROPERTIES COMPILE_DEFINITIONS "E300_NATIVE=1"
- )
- endif(UDEV_FOUND AND NOT E300_FORCE_NETWORK)
-
- if(ENABLE_GPSD)
- set_source_files_properties(
- ${CMAKE_CURRENT_SOURCE_DIR}/e300_impl.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/e300_impl.hpp
- ${CMAKE_CURRENT_SOURCE_DIR}/e3xx_radio_ctrl_impl.cpp
- PROPERTIES COMPILE_DEFINITIONS "E300_GPSD=1"
- )
- endif(ENABLE_GPSD)
-endif(ENABLE_E300)
diff --git a/host/lib/usrp/e300/e300_common.cpp b/host/lib/usrp/e300/e300_common.cpp
deleted file mode 100644
index cd52bb9d0..000000000
--- a/host/lib/usrp/e300/e300_common.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-//
-// Copyright 2014-2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-#include <uhd/image_loader.hpp>
-#include <uhd/utils/log.hpp>
-#include <uhd/utils/paths.hpp>
-#include <uhd/utils/static.hpp>
-
-#include "e300_impl.hpp"
-#include "e300_fifo_config.hpp"
-#include "e300_fifo_config.hpp"
-
-#include "e300_common.hpp"
-
-#include <boost/filesystem.hpp>
-#include <fstream>
-#include <string>
-
-#ifdef E300_NATIVE
-namespace uhd { namespace usrp { namespace e300 {
-
-namespace common {
-
-void load_fpga_image(const std::string &path)
-{
- if (not boost::filesystem::exists("/dev/xdevcfg"))
- ::system("mknod /dev/xdevcfg c 259 0");
-
- UHD_LOGGER_INFO("E300") << "Loading FPGA image: " << path << "...";
-
- std::ifstream fpga_file(path.c_str(), std::ios_base::binary);
- UHD_ASSERT_THROW(fpga_file.good());
-
- std::FILE *wfile;
- wfile = std::fopen("/dev/xdevcfg", "wb");
- UHD_ASSERT_THROW(!(wfile == NULL));
-
- char buff[16384]; // devcfg driver can't handle huge writes
- do {
- fpga_file.read(buff, sizeof(buff));
- std::fwrite(buff, 1, size_t(fpga_file.gcount()), wfile);
- } while (fpga_file);
-
- fpga_file.close();
- std::fclose(wfile);
-
- UHD_LOGGER_INFO("E300") << "FPGA image loaded";
-}
-
-static bool e300_image_loader(const image_loader::image_loader_args_t &image_loader_args) {
- // Make sure this is an E3x0 and we don't want to use anything connected
- uhd::device_addrs_t devs = e300_find(image_loader_args.args);
- if(devs.size() == 0 or !image_loader_args.load_fpga) return false;
-
- std::string fpga_filename, idle_image; // idle_image never used, just needed for function
- if(image_loader_args.fpga_path == "") {
- get_e3x0_fpga_images(devs[0], fpga_filename, idle_image);
- }
- else {
- if(not boost::filesystem::exists(image_loader_args.fpga_path)) {
- throw uhd::runtime_error(str(boost::format("The path \"%s\" does not exist.")
- % image_loader_args.fpga_path));
- }
- else fpga_filename = image_loader_args.fpga_path;
- }
-
- load_fpga_image(fpga_filename);
- return true;
-}
-
-UHD_STATIC_BLOCK(register_e300_image_loader) {
- std::string recovery_instructions = "The default FPGA image will be loaded the next "
- "time UHD uses this device.";
-
- image_loader::register_image_loader("e3x0", e300_image_loader, recovery_instructions);
-}
-
-}
-
-}}}
-
-#else
-namespace uhd { namespace usrp { namespace e300 {
-
-namespace common {
-
-void load_fpga_image(const std::string&)
-{
- throw uhd::assertion_error("load_fpga_image() !E300_NATIVE");
-}
-
-}
-
-}}}
-#endif
diff --git a/host/lib/usrp/e300/e300_common.hpp b/host/lib/usrp/e300/e300_common.hpp
deleted file mode 100644
index 8624f0e3c..000000000
--- a/host/lib/usrp/e300/e300_common.hpp
+++ /dev/null
@@ -1,21 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_E300_COMMON_HPP
-#define INCLUDED_E300_COMMON_HPP
-
-namespace uhd { namespace usrp { namespace e300 {
-
-namespace common {
-
-void load_fpga_image(const std::string &path);
-
-};
-
-}}}
-
-#endif // INCLUDED_E300_COMMON_HPP
diff --git a/host/lib/usrp/e300/e300_defaults.hpp b/host/lib/usrp/e300/e300_defaults.hpp
deleted file mode 100644
index 97b0ddc3f..000000000
--- a/host/lib/usrp/e300/e300_defaults.hpp
+++ /dev/null
@@ -1,74 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_E300_DEFAULTS_HPP
-#define INCLUDED_E300_DEFAULTS_HPP
-
-#include "ad9361_client.h"
-
-namespace uhd { namespace usrp { namespace e300 {
-
-static const double DEFAULT_TICK_RATE = 32e6;
-static const double MIN_TICK_RATE = 10e6;
-
-static const double DEFAULT_TX_SAMP_RATE = 1.0e6;
-static const double DEFAULT_RX_SAMP_RATE = 1.0e6;
-static const double DEFAULT_DDC_FREQ = 0.0;
-static const double DEFAULT_DUC_FREQ = 0.0;
-
-static const std::string DEFAULT_TIME_SRC = "internal";
-static const std::string DEFAULT_CLOCK_SRC = "internal";
-
-static const size_t DEFAULT_RX_DATA_FRAME_SIZE = 4096;
-static const size_t DEFAULT_RX_DATA_NUM_FRAMES = 32;
-
-static const size_t DEFAULT_TX_DATA_FRAME_SIZE = 4096;
-static const size_t DEFAULT_TX_DATA_NUM_FRAMES = 32;
-
-static const size_t DEFAULT_CTRL_FRAME_SIZE = 64;
-static const size_t DEFAULT_CTRL_NUM_FRAMES = 32;
-
-static const size_t MAX_NET_RX_DATA_FRAME_SIZE = 1200;
-static const size_t MAX_NET_TX_DATA_FRAME_SIZE = 1200;
-
-static const size_t MAX_AXI_RX_DATA_FRAME_SIZE = 4096;
-static const size_t MAX_AXI_TX_DATA_FRAME_SIZE = 4096;
-
-static const size_t MAX_DMA_CHANNEL_PAIRS = 16;
-
-static const double AD9361_SPI_RATE = 8e6;
-
-class e300_ad9361_client_t : public ad9361_params {
-public:
- ~e300_ad9361_client_t() {}
- double get_band_edge(frequency_band_t band) {
- switch (band) {
- case AD9361_RX_BAND0: return 1.2e9;
- case AD9361_RX_BAND1: return 2.6e9;
- case AD9361_TX_BAND0: return 2940.0e6;
- default: return 0;
- }
- }
- clocking_mode_t get_clocking_mode() {
- return clocking_mode_t::AD9361_XTAL_N_CLK_PATH;
- }
- digital_interface_mode_t get_digital_interface_mode() {
- return AD9361_DDR_FDD_LVCMOS;
- }
- digital_interface_delays_t get_digital_interface_timing() {
- digital_interface_delays_t delays;
- delays.rx_clk_delay = 0;
- delays.rx_data_delay = 0xF;
- delays.tx_clk_delay = 0;
- delays.tx_data_delay = 0xF;
- return delays;
- }
-};
-
-}}} // namespace
-
-#endif // INCLUDED_E300_DEFAULTS_HPP
diff --git a/host/lib/usrp/e300/e300_eeprom_manager.cpp b/host/lib/usrp/e300/e300_eeprom_manager.cpp
deleted file mode 100644
index 6547048ec..000000000
--- a/host/lib/usrp/e300/e300_eeprom_manager.cpp
+++ /dev/null
@@ -1,241 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "e300_eeprom_manager.hpp"
-#include <uhd/types/mac_addr.hpp>
-#include <uhd/utils/byteswap.hpp>
-
-namespace uhd { namespace usrp { namespace e300 {
-
-static const std::string _bytes_to_string(const uint8_t* bytes, size_t max_len)
-{
- std::string out;
- for (size_t i = 0; i < max_len; i++) {
- if (bytes[i] < 32 or bytes[i] > 127) return out;
- out += bytes[i];
- }
- return out;
-}
-
-static void _string_to_bytes(const std::string &string, size_t max_len, uint8_t* buffer)
-{
- byte_vector_t bytes;
- const size_t len = std::min(string.size(), max_len);
- for (size_t i = 0; i < len; i++){
- buffer[i] = string[i];
- }
- if (len < max_len)
- buffer[len] = '\0';
-}
-
-e300_eeprom_manager::e300_eeprom_manager(i2c::sptr i2c) : _i2c(i2c)
-{
- read_mb_eeprom();
- read_db_eeprom();
-}
-
-e300_eeprom_manager::~e300_eeprom_manager(void)
-{
-}
-
-const mboard_eeprom_t& e300_eeprom_manager::read_mb_eeprom(void)
-{
- boost::mutex::scoped_lock(_mutex);
-
- std::vector<uint8_t> bytes;
- bytes.resize(sizeof(mb_eeprom_map_t));
- mb_eeprom_map_t *map_ptr = reinterpret_cast<mb_eeprom_map_t*>(&bytes[0]);
- memset(map_ptr, 0xff, sizeof(mb_eeprom_map_t));
-
- // get the old contents
- for(size_t i = 0; i < sizeof(mb_eeprom_map_t); i++)
- bytes[i] = _i2c->get_i2c_reg8(MB_ADDR, i);
-
- mb_eeprom_map_t &map = *map_ptr;
-
- _mb_eeprom["product"] = std::to_string(
- uhd::ntohx<uint16_t>(map.hw_product));
- _mb_eeprom["revision"] = std::to_string(
- uhd::ntohx<uint16_t>(map.hw_revision));
- _mb_eeprom["serial"] = _bytes_to_string(
- map.serial, MB_SERIAL_LEN);
-
- byte_vector_t mac_addr(map.mac_addr, map.mac_addr + 6);
- _mb_eeprom["mac-addr"] = mac_addr_t::from_bytes(mac_addr).to_string();
-
- _mb_eeprom["name"] = _bytes_to_string(
- map.user_name, MB_NAME_LEN);
-
- return _mb_eeprom;
-}
-
-const dboard_eeprom_t& e300_eeprom_manager::read_db_eeprom(void)
-{
- boost::mutex::scoped_lock(_mutex);
-
- std::vector<uint8_t> bytes;
- bytes.resize(sizeof(db_eeprom_map_t));
- db_eeprom_map_t *map_ptr = reinterpret_cast<db_eeprom_map_t*>(&bytes[0]);
- memset(map_ptr, 0xff, sizeof(db_eeprom_map_t));
-
- // get the old contents
- for(size_t i = 0; i < sizeof(db_eeprom_map_t); i++)
- bytes[i] = _i2c->get_i2c_reg16(DB_ADDR, i);
-
- db_eeprom_map_t &map = *map_ptr;
-
- _db_eeprom.id = uhd::usrp::dboard_id_t::from_uint16(
- uhd::ntohx<uint16_t>(map.hw_product));
-
- _db_eeprom.revision = std::to_string(
- uhd::ntohx<uint16_t>(map.hw_revision));
- _db_eeprom.serial = _bytes_to_string(
- map.serial, DB_SERIAL_LEN);
-
- return _db_eeprom;
-}
-
-void e300_eeprom_manager::write_db_eeprom(const dboard_eeprom_t& eeprom)
-{
- boost::mutex::scoped_lock(_mutex);
- _db_eeprom = eeprom;
- std::vector<uint8_t> bytes;
- bytes.resize(sizeof(db_eeprom_map_t));
-
-
- db_eeprom_map_t *map_ptr = reinterpret_cast<db_eeprom_map_t*>(&bytes[0]);
- memset(map_ptr, 0xff, sizeof(db_eeprom_map_t));
-
- // get the old contents
- for(size_t i = 0; i < sizeof(db_eeprom_map_t); i++)
- bytes[i] = _i2c->get_i2c_reg16(DB_ADDR, i);
-
- db_eeprom_map_t &map = *map_ptr;
-
- // set the data version, that can be used to distinguish eeprom layouts
- map.data_version_major = E310_DB_MAP_MAJOR;
- map.data_version_minor = E310_DB_MAP_MINOR;
-
- if (_db_eeprom.id != dboard_id_t::none()) {
- map.hw_product = uhd::htonx<uint16_t>(
- _db_eeprom.id.to_uint16());
- }
-
- if (not _db_eeprom.revision.empty()) {
- map.hw_revision = uhd::htonx<uint16_t>(
- boost::lexical_cast<uint16_t>(_db_eeprom.revision));
- }
-
- if (not _db_eeprom.serial.empty()) {
- _string_to_bytes(_db_eeprom.serial, DB_SERIAL_LEN, map.serial);
- }
- for(size_t i = 0; i < sizeof(mb_eeprom_map_t); i++)
- _i2c->set_i2c_reg16(DB_ADDR, i, bytes[i]);
-}
-
-void e300_eeprom_manager::write_mb_eeprom(const mboard_eeprom_t& eeprom)
-{
- boost::mutex::scoped_lock(_mutex);
- _mb_eeprom = eeprom;
- std::vector<uint8_t> bytes;
- bytes.resize(sizeof(mb_eeprom_map_t));
-
-
- mb_eeprom_map_t *map_ptr = reinterpret_cast<mb_eeprom_map_t*>(&bytes[0]);
- memset(map_ptr, 0xff, sizeof(mb_eeprom_map_t));
-
- // get the old contents
- for(size_t i = 0; i < sizeof(mb_eeprom_map_t); i++)
- bytes[i] = _i2c->get_i2c_reg8(MB_ADDR, i);
-
- mb_eeprom_map_t &map = *map_ptr;
-
- // set the data version, that can be used to distinguish eeprom layouts
- map.data_version_major = E310_MB_MAP_MAJOR;
- map.data_version_minor = E310_MB_MAP_MINOR;
-
-
- if (_mb_eeprom.has_key("product")) {
- map.hw_product = uhd::htonx<uint16_t>(
- boost::lexical_cast<uint16_t>(_mb_eeprom["product"]));
- }
- if (_mb_eeprom.has_key("revision")) {
- map.hw_revision = uhd::htonx<uint16_t>(
- boost::lexical_cast<uint16_t>(_mb_eeprom["revision"]));
- }
- if (_mb_eeprom.has_key("serial")) {
- _string_to_bytes(_mb_eeprom["serial"], MB_SERIAL_LEN, map.serial);
- }
- if (_mb_eeprom.has_key("mac-addr")) {
- byte_vector_t mac_addr = mac_addr_t::from_string(_mb_eeprom["mac-addr"]).to_bytes();
- std::copy(mac_addr.begin(), mac_addr.end(), map.mac_addr);
- }
-
- //store the name
- if (_mb_eeprom.has_key("name")) {
- _string_to_bytes(_mb_eeprom["name"], MB_NAME_LEN, map.user_name);
- }
-
- for(size_t i = 0; i < sizeof(mb_eeprom_map_t); i++)
- _i2c->set_i2c_reg8(MB_ADDR, i, bytes[i]);
-
-}
-
-e300_eeprom_manager::mboard_t e300_eeprom_manager::get_mb_type(void) const
-{
- boost::mutex::scoped_lock(_mutex);
- uint16_t pid = boost::lexical_cast<uint16_t>(
- _mb_eeprom["product"]);
- return get_mb_type(pid);
-}
-
-e300_eeprom_manager::mboard_t e300_eeprom_manager::get_mb_type(
- uint16_t pid)
-{
- switch (pid) {
- case E300_MB_PID:
- return USRP_E300_MB;
-
- case E310_SG1_MB_PID:
- return USRP_E310_SG1_MB;
-
- case E310_SG3_MB_PID:
- return USRP_E310_SG3_MB;
-
- default:
- return UNKNOWN;
- };
-}
-
-
-std::string e300_eeprom_manager::get_mb_type_string(void) const
-{
- boost::mutex::scoped_lock(_mutex);
- uint16_t product = boost::lexical_cast<uint16_t>(
- _mb_eeprom["product"]);
- switch (product) {
- case E300_MB_PID:
- return "E3XX";
-
- case E310_SG1_MB_PID:
- return "E3XX SG1";
-
- case E310_SG3_MB_PID:
- return "E3XX SG3";
-
- default:
- return "UNKNOWN";
- };
-}
-
-i2c::sptr e300_eeprom_manager::get_i2c_sptr(void)
-{
- return _i2c;
-}
-
-
-}}} // namespace
diff --git a/host/lib/usrp/e300/e300_eeprom_manager.hpp b/host/lib/usrp/e300/e300_eeprom_manager.hpp
deleted file mode 100644
index ee4497211..000000000
--- a/host/lib/usrp/e300/e300_eeprom_manager.hpp
+++ /dev/null
@@ -1,122 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_E300_EEPROM_MANAGER_HPP
-#define INCLUDED_E300_EEPROM_MANAGER_HPP
-
-#include <boost/thread/mutex.hpp>
-#include <boost/shared_ptr.hpp>
-#include <uhd/types/dict.hpp>
-#include <uhd/usrp/mboard_eeprom.hpp>
-#include <uhd/usrp/dboard_eeprom.hpp>
-
-#include "e300_i2c.hpp"
-
-namespace uhd { namespace usrp { namespace e300 {
-
-static const uint16_t E300_MB_PID = 0x77d1;
-static const uint16_t E310_SG1_MB_PID = 0x77d2;
-static const uint16_t E310_SG3_MB_PID = 0x77d3;
-
-static const uint16_t E300_DB_PID = 0x0100;
-static const uint16_t E310_DB_PID = 0x0110;
-
-static const uint16_t E310_MB_MAP_MAJOR = 0x0001;
-static const uint16_t E310_MB_MAP_MINOR = 0x0000;
-
-static const uint16_t E310_DB_MAP_MAJOR = 0x0001;
-static const uint16_t E310_DB_MAP_MINOR = 0x0000;
-
-class e300_eeprom_manager : uhd::noncopyable
-{
-public:
- typedef boost::shared_ptr<e300_eeprom_manager> sptr;
- e300_eeprom_manager(i2c::sptr i2c);
- ~e300_eeprom_manager();
-
- // mboard
- const mboard_eeprom_t& read_mb_eeprom();
- void write_mb_eeprom(const mboard_eeprom_t& eeprom);
-
- UHD_INLINE const mboard_eeprom_t& get_mb_eeprom()
- {
- return _mb_eeprom;
- }
-
- // dboard
- const dboard_eeprom_t& read_db_eeprom();
- void write_db_eeprom(const dboard_eeprom_t& eeprom);
-
- UHD_INLINE const dboard_eeprom_t& get_db_eeprom()
- {
- return _db_eeprom;
- }
-
-
- i2c::sptr get_i2c_sptr(void);
-
- enum mboard_t {USRP_E300_MB, USRP_E310_SG1_MB, USRP_E310_SG3_MB, UNKNOWN};
-
- mboard_t get_mb_type(void) const;
- static mboard_t get_mb_type(uint16_t pid);
- std::string get_mb_type_string(void) const;
-
-private: // types
- const static size_t MB_SERIAL_LEN = 8;
- const static size_t MB_NAME_LEN = 32;
- const static size_t MB_ADDR = 0x51;
-
- const static size_t DB_SERIAL_LEN = 8;
- const static size_t DB_ADDR = 0x50;
-
- struct mb_eeprom_map_t
- {
- // Data format version
- uint16_t data_version_major;
- uint16_t data_version_minor;
-
- // NIC mac address
- uint8_t mac_addr[6];
-
- // HW identification info
- uint16_t hw_product;
- uint16_t hw_revision;
-
- // serial
- uint8_t serial[MB_SERIAL_LEN];
- uint8_t pad[20 - MB_SERIAL_LEN];
-
- //User specific
- uint8_t user_name[MB_NAME_LEN];
- };
-
- struct db_eeprom_map_t
- {
- // Data format version
- uint16_t data_version_major;
- uint16_t data_version_minor;
-
- // HW identification info
- uint16_t hw_product;
- uint16_t hw_revision;
-
- // serial
- uint8_t serial[DB_SERIAL_LEN];
- uint8_t pad[20 - DB_SERIAL_LEN];
- };
-
-private: // members
- mboard_eeprom_t _mb_eeprom;
- dboard_eeprom_t _db_eeprom;
- i2c::sptr _i2c;
-
- boost::mutex _mutex;
-};
-
-}}} //namespace
-
-#endif // INCLUDED_E300_EEPROM_MANAGER_HPP
diff --git a/host/lib/usrp/e300/e300_fifo_config.cpp b/host/lib/usrp/e300/e300_fifo_config.cpp
deleted file mode 100644
index e34b56ed4..000000000
--- a/host/lib/usrp/e300/e300_fifo_config.cpp
+++ /dev/null
@@ -1,437 +0,0 @@
-//
-// Copyright 2013-2017 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifdef E300_NATIVE
-
-#include <uhdlib/utils/system_time.hpp>
-#include <uhd/config.hpp>
-#include <stdint.h>
-#include <atomic>
-#include <chrono>
-#include <thread>
-
-// constants coded into the fpga parameters
-static const size_t ZF_CONFIG_BASE = 0x40000000;
-static const size_t ZF_PAGE_WIDTH = 10;
-static const size_t H2S_STREAMS_WIDTH = 4;
-static const size_t H2S_CMDFIFO_DEPTH = 5;
-static const size_t S2H_STREAMS_WIDTH = 4;
-static const size_t S2H_CMDFIFO_DEPTH = 5;
-
-// calculate more useful constants for this module
-static const size_t ZF_PAGE_SIZE(1 << ZF_PAGE_WIDTH);
-static const size_t H2S_NUM_STREAMS(1 << H2S_STREAMS_WIDTH);
-static const size_t H2S_NUM_CMDS(1 << H2S_CMDFIFO_DEPTH);
-static const size_t S2H_NUM_STREAMS(1 << S2H_STREAMS_WIDTH);
-static const size_t S2H_NUM_CMDS(1 << S2H_CMDFIFO_DEPTH);
-
-//offsetsinto the arbiter memory map
-static const size_t ARBITER_WR_CLEAR = 0;
-static const size_t ARBITER_RD_SIG = 0;
-static const size_t ARBITER_WR_ADDR = 4;
-static const size_t ARBITER_WR_SIZE = 8;
-static const size_t ARBITER_WR_STS_RDY = 12;
-static const size_t ARBITER_WR_STS = 16;
-static const size_t ARBITER_RB_STATUS = 16;
-static const size_t ARBITER_RB_STATUS_OCC = 20;
-static const size_t ARBITER_RB_ADDR_SPACE = 24;
-static const size_t ARBITER_RB_SIZE_SPACE = 28;
-
-// registers for the wb32_iface
-static const size_t SR_CORE_READBACK = 0;
-
-
-static UHD_INLINE size_t S2H_BASE(const size_t base)
-{
- return base + ZF_PAGE_SIZE * 0;
-}
-
-static UHD_INLINE size_t H2S_BASE(const size_t base)
-{
- return base + ZF_PAGE_SIZE * 1;
-}
-
-static UHD_INLINE size_t REG_BASE(const size_t base)
-{
- return base + ZF_PAGE_SIZE * 2;
-}
-
-static UHD_INLINE size_t DST_BASE(const size_t base)
-{
- return base + ZF_PAGE_SIZE * 3;
-}
-
-static UHD_INLINE size_t ZF_STREAM_OFF(const size_t which)
-{
- return which * 32;
-}
-
-#include "e300_fifo_config.hpp"
-#include <sys/mman.h> //mmap
-#include <fcntl.h> //open, close
-#include <poll.h> //poll
-#include <uhd/utils/log.hpp>
-
-#include <boost/format.hpp>
-#include <boost/thread/thread.hpp> //sleep
-#include <uhd/types/time_spec.hpp> //timeout
-#include <uhd/utils/log.hpp>
-#include <uhdlib/utils/atomic.hpp>
-
-//locking stuff for shared irq
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/condition_variable.hpp>
-
-struct e300_fifo_poll_waiter
-{
- e300_fifo_poll_waiter(const int fd):
- _fd(fd),
- _poll_claimed(false)
- {
- //NOP
- }
-
- /*!
- * Waits until the file descriptor fd has data to read.
- * Access to the file descriptor is thread safe.
- */
- void wait(const double timeout)
- {
- if (timeout == 0) {
- return;
- }
-
- boost::mutex::scoped_lock l(_mutex);
- if (_poll_claimed)
- {
- _cond.timed_wait(l, boost::posix_time::microseconds(long(timeout*1000000)));
- }
- else
- {
- _poll_claimed = true;
- l.unlock();
- struct pollfd fds[1];
- fds[0].fd = _fd;
- fds[0].events = POLLIN;
- ::poll(fds, 1, long(timeout*1000));
- if (fds[0].revents & POLLIN)
- ::read(_fd, NULL, 0);
-
- l.lock();
- _poll_claimed = 0;
- _cond.notify_all();
- }
- }
-
- boost::condition_variable _cond;
- boost::mutex _mutex;
- int _fd;
- bool _poll_claimed;
-};
-
-static const size_t DEFAULT_FRAME_SIZE = 2048;
-static const size_t DEFAULT_NUM_FRAMES = 32;
-
-using namespace uhd;
-using namespace uhd::transport;
-
-struct __mem_addrz_t
-{
- size_t which, phys, data, ctrl;
-};
-
-/***********************************************************************
- * peek n' poke mmapped space
- **********************************************************************/
-UHD_INLINE void zf_poke32(const uint32_t addr, const uint32_t data)
-{
- volatile uint32_t *p = reinterpret_cast<uint32_t *>(addr);
- *p = data;
-}
-
-UHD_INLINE uint32_t zf_peek32(const uint32_t addr)
-{
- volatile const uint32_t *p = reinterpret_cast<const uint32_t *>(addr);
- return *p;
-}
-
-/***********************************************************************
- * managed buffer
- **********************************************************************/
-struct e300_fifo_mb : managed_buffer
-{
- e300_fifo_mb(const __mem_addrz_t &addrs, const size_t len):
- ctrl_base(addrs.ctrl), phys_mem(addrs.phys), mem((void *)addrs.data), len(len){}
-
- void release(void)
- {
- UHD_ASSERT_THROW(zf_peek32(ctrl_base+ARBITER_RB_ADDR_SPACE) > 0);
- UHD_ASSERT_THROW(zf_peek32(ctrl_base+ARBITER_RB_SIZE_SPACE) > 0);
- zf_poke32(ctrl_base + ARBITER_WR_ADDR, phys_mem);
- zf_poke32(ctrl_base + ARBITER_WR_SIZE, this->size());
- }
-
- template <typename T>
- UHD_INLINE typename T::sptr get_new(void)
- {
- return make(reinterpret_cast<T *>(this), mem, len);
- }
-
- const size_t ctrl_base;
- const size_t phys_mem;
- void *const mem;
- const size_t len;
-};
-
-/***********************************************************************
- * transport
- **********************************************************************/
-class e300_transport : public zero_copy_if
-{
-public:
- e300_transport(
- boost::shared_ptr<void> allocator,
- const __mem_addrz_t &addrs,
- const size_t num_frames,
- const size_t frame_size,
- e300_fifo_poll_waiter *waiter,
- const bool auto_release
- ):
- _allocator(allocator),
- _addrs(addrs),
- _num_frames(num_frames),
- _frame_size(frame_size),
- _index(0),
- _waiter(waiter)
- {
- //UHD_LOGGER_INFO("E300") << boost::format("phys 0x%x") % addrs.phys ;
- //UHD_LOGGER_INFO("E300") << boost::format("data 0x%x") % addrs.data ;
- //UHD_LOGGER_INFO("E300") << boost::format("ctrl 0x%x") % addrs.ctrl ;
-
- const uint32_t sig = zf_peek32(_addrs.ctrl + ARBITER_RD_SIG);
- UHD_ASSERT_THROW((sig >> 16) == 0xACE0);
-
- zf_poke32(_addrs.ctrl + ARBITER_WR_CLEAR, 1);
- for (size_t i = 0; i < num_frames; i++)
- {
- //create a managed buffer at the given offset
- __mem_addrz_t mb_addrs = addrs;
- mb_addrs.phys += (i*frame_size);
- mb_addrs.data += (i*frame_size);
- boost::shared_ptr<e300_fifo_mb> mb(new e300_fifo_mb(mb_addrs, frame_size));
-
- //setup the buffers so they are "positioned for use"
- const size_t sts_good = (1 << 7) | (_addrs.which & 0xf);
- if (auto_release) mb->get_new<managed_recv_buffer>(); //release for read
- else zf_poke32(_addrs.ctrl + ARBITER_WR_STS, sts_good); //poke an ok into the sts fifo
-
- _buffs.push_back(mb);
- }
- }
-
- ~e300_transport(void)
- {
- //NOP
- }
-
- template <typename T>
- UHD_INLINE typename T::sptr get_buff(const double timeout)
- {
- const time_spec_t exit_time = uhd::get_system_time() + time_spec_t(timeout);
- while (1)
- {
- if (zf_peek32(_addrs.ctrl + ARBITER_RB_STATUS_OCC))
- {
- const uint32_t sts = zf_peek32(_addrs.ctrl + ARBITER_RB_STATUS);
- UHD_ASSERT_THROW((sts >> 7) & 0x1); //assert OK
- UHD_ASSERT_THROW((sts & 0xf) == _addrs.which); //expected tag
- zf_poke32(_addrs.ctrl + ARBITER_WR_STS_RDY, 1); //pop from sts fifo
- if (_index == _num_frames)
- _index = 0;
- return _buffs[_index++]->get_new<T>();
- }
- if (uhd::get_system_time() > exit_time) {
- break;
- }
- _waiter->wait(timeout);
- //std::this_thread::sleep_for(std::chrono::milliseconds(1));
- }
-
- return typename T::sptr();
- }
-
- managed_recv_buffer::sptr get_recv_buff(const double timeout)
- {
- return this->get_buff<managed_recv_buffer>(timeout);
- }
-
- size_t get_num_recv_frames(void) const
- {
- return _num_frames;
- }
-
- size_t get_recv_frame_size(void) const
- {
- return _frame_size;
- }
-
- managed_send_buffer::sptr get_send_buff(const double timeout)
- {
- return this->get_buff<managed_send_buffer>(timeout);
- }
-
- size_t get_num_send_frames(void) const
- {
- return _num_frames;
- }
-
- size_t get_send_frame_size(void) const
- {
- return _frame_size;
- }
-
-private:
- boost::shared_ptr<void> _allocator;
- const __mem_addrz_t _addrs;
- const size_t _num_frames;
- const size_t _frame_size;
- size_t _index;
- e300_fifo_poll_waiter *_waiter;
- std::vector<boost::shared_ptr<e300_fifo_mb> > _buffs;
-};
-
-/***********************************************************************
- * memory mapping
- **********************************************************************/
-class e300_fifo_interface_impl : public virtual e300_fifo_interface
-{
-public:
- e300_fifo_interface_impl(const e300_fifo_config_t &config):
- _config(config),
- _bytes_in_use(0),
- _recv_entries_in_use(std::vector<size_t>(S2H_NUM_STREAMS, 0)),
- _send_entries_in_use(std::vector<size_t>(H2S_NUM_STREAMS, 0))
- {
- //open the file descriptor to our kernel module
- const std::string dev = "/dev/axi_fpga";
- _fd = ::open(dev.c_str(), O_RDWR|O_SYNC);
- if (_fd < 0)
- {
- throw uhd::runtime_error("e300: failed to open " + dev);
- }
-
- //mmap the control and data regions into virtual space
- //UHD_VAR(_config.ctrl_length);
- //UHD_VAR(_config.buff_length);
- //UHD_VAR(_config.phys_addr);
- _buff = ::mmap(NULL, _config.ctrl_length + _config.buff_length, PROT_READ|PROT_WRITE, MAP_SHARED, _fd, 0);
- if (_buff == MAP_FAILED)
- {
- ::close(_fd);
- throw uhd::runtime_error("e300: failed to mmap " + dev);
- }
-
- //segment the memory according to zynq fifo arbiter
- _ctrl_space = size_t(_buff);
- _data_space = size_t(_buff) + _config.ctrl_length;
-
- //zero out the data region
- std::memset((void *)_data_space, 0, _config.buff_length);
-
- //create a poll _waiter for the transports
- _waiter = new e300_fifo_poll_waiter(_fd);
- }
-
- virtual ~e300_fifo_interface_impl(void)
- {
- delete _waiter;
- UHD_LOGGER_TRACE("E300")<< "cleanup: munmap" ;
- ::munmap(_buff, _config.ctrl_length + _config.buff_length);
- ::close(_fd);
- }
-
- uhd::transport::zero_copy_if::sptr make_recv_xport(
- const size_t which_stream,
- const uhd::transport::zero_copy_xport_params &params)
- {
- return this->_make_xport(which_stream, params, true);
- }
-
- uhd::transport::zero_copy_if::sptr make_send_xport(
- const size_t which_stream,
- const uhd::transport::zero_copy_xport_params &params)
- {
- return this->_make_xport(which_stream, params, false);
- }
-
- size_t get_global_regs_base() const
- {
- return REG_BASE(_ctrl_space);
- }
-
-private:
- uhd::transport::zero_copy_if::sptr _make_xport(
- const size_t which_stream,
- const uhd::transport::zero_copy_xport_params &params,
- const bool is_recv)
- {
- boost::mutex::scoped_lock lock(_setup_mutex);
-
- const size_t frame_size = is_recv ? params.recv_frame_size : params.send_frame_size;
- const size_t num_frames = is_recv ? params.num_recv_frames : params.num_send_frames;
- size_t &entries_in_use = (is_recv)? _recv_entries_in_use.at(which_stream)
- : _send_entries_in_use.at(which_stream);
-
- __mem_addrz_t addrs;
- addrs.which = which_stream;
- addrs.phys = _config.phys_addr + _bytes_in_use;
- addrs.data = _data_space + _bytes_in_use;
- addrs.ctrl = ((is_recv)? S2H_BASE(_ctrl_space) : H2S_BASE(_ctrl_space)) + ZF_STREAM_OFF(which_stream);
-
- uhd::transport::zero_copy_if::sptr xport;
- if (is_recv) xport.reset(new e300_transport(shared_from_this(), addrs, num_frames, frame_size, _waiter, is_recv));
- else xport.reset(new e300_transport(shared_from_this(), addrs, num_frames, frame_size, _waiter, is_recv));
-
- _bytes_in_use += num_frames*frame_size;
- entries_in_use += num_frames;
-
- UHD_ASSERT_THROW(_recv_entries_in_use.at(which_stream) <= S2H_NUM_CMDS);
- UHD_ASSERT_THROW(_send_entries_in_use.at(which_stream) <= H2S_NUM_CMDS);
- UHD_ASSERT_THROW(_bytes_in_use <= _config.buff_length);
-
-
- return xport;
- }
-
- e300_fifo_config_t _config;
- e300_fifo_poll_waiter *_waiter;
- size_t _bytes_in_use;
- int _fd;
- void *_buff;
- size_t _ctrl_space;
- size_t _data_space;
- std::vector<size_t> _recv_entries_in_use;
- std::vector<size_t> _send_entries_in_use;
- boost::mutex _setup_mutex;
-};
-
-e300_fifo_interface::sptr e300_fifo_interface::make(const e300_fifo_config_t &config)
-{
- return e300_fifo_interface::sptr(new e300_fifo_interface_impl(config));
-}
-
-#else //E300_NATIVE
-
-#include "e300_fifo_config.hpp"
-#include <uhd/exception.hpp>
-
-e300_fifo_interface::sptr e300_fifo_interface::make(const e300_fifo_config_t &)
-{
- throw uhd::assertion_error("e300_fifo_interface::make() !E300_NATIVE");
-}
-
-#endif //E300_NATIVE
diff --git a/host/lib/usrp/e300/e300_fifo_config.hpp b/host/lib/usrp/e300/e300_fifo_config.hpp
deleted file mode 100644
index fa6b00eec..000000000
--- a/host/lib/usrp/e300/e300_fifo_config.hpp
+++ /dev/null
@@ -1,42 +0,0 @@
-//
-// Copyright 2013-2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_E300_FIFO_CONFIG_HPP
-#define INCLUDED_E300_FIFO_CONFIG_HPP
-
-#include <uhd/types/device_addr.hpp>
-#include <uhd/types/wb_iface.hpp>
-#include <uhd/transport/zero_copy.hpp>
-#include <boost/enable_shared_from_this.hpp>
-
-struct e300_fifo_config_t
-{
- size_t ctrl_length;
- size_t buff_length;
- size_t phys_addr;
-};
-
-e300_fifo_config_t e300_read_sysfs(void);
-std::string e300_get_sysfs_attr(const std::string &node, const std::string &attr);
-
-struct e300_fifo_interface : boost::enable_shared_from_this<e300_fifo_interface>
-{
- typedef boost::shared_ptr<e300_fifo_interface> sptr;
- static sptr make(const e300_fifo_config_t &config);
-
- virtual uhd::transport::zero_copy_if::sptr make_recv_xport(
- const size_t which_stream,
- const uhd::transport::zero_copy_xport_params &params) = 0;
-
- virtual uhd::transport::zero_copy_if::sptr make_send_xport(
- const size_t which_stream,
- const uhd::transport::zero_copy_xport_params &parms) = 0;
-
- virtual size_t get_global_regs_base(void) const = 0;
-};
-
-#endif /* INCLUDED_E300_FIFO_CONFIG_HPP */
diff --git a/host/lib/usrp/e300/e300_fpga_defs.hpp b/host/lib/usrp/e300/e300_fpga_defs.hpp
deleted file mode 100644
index 517aa4653..000000000
--- a/host/lib/usrp/e300/e300_fpga_defs.hpp
+++ /dev/null
@@ -1,19 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_E300_FPGA_DEFS_HPP
-#define INCLUDED_E300_FPGA_DEFS_HPP
-namespace uhd { namespace usrp { namespace e300 { namespace fpga {
-
-static const size_t NUM_RADIOS = 2;
-
-static const uint32_t COMPAT_MAJOR = 255;
-static const uint32_t COMPAT_MINOR = 0;
-
-}}}} // namespace
-
-#endif // INCLUDED_E300_FPGA_DEFS_HPP
diff --git a/host/lib/usrp/e300/e300_global_regs.cpp b/host/lib/usrp/e300/e300_global_regs.cpp
deleted file mode 100644
index ef607797a..000000000
--- a/host/lib/usrp/e300/e300_global_regs.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "e300_global_regs.hpp"
-
-#include <stdint.h>
-#include <uhd/exception.hpp>
-#include <uhd/utils/byteswap.hpp>
-#include <cstring>
-#include <iostream>
-
-namespace uhd { namespace usrp { namespace e300 {
-
-class global_regs_local_impl : public global_regs
-{
-public:
- global_regs_local_impl(const size_t ctrl_base) : _ctrl_base(ctrl_base)
- {
- }
-
- virtual ~global_regs_local_impl(void)
- {
- }
-
- uint32_t peek32(const uhd::wb_iface::wb_addr_type addr)
- {
- // setup readback register
- _poke32(_ctrl_base + global_regs::SR_CORE_READBACK, addr);
- return _peek32(_ctrl_base);
- }
-
- void poke32(const uhd::wb_iface::wb_addr_type addr, const uint32_t data)
- {
- _poke32(_ctrl_base + static_cast<size_t>(addr), data);
- }
-
-
-private:
- const size_t _ctrl_base;
-
- UHD_INLINE void _poke32(const uint32_t addr, const uint32_t data)
- {
- volatile uint32_t *p = reinterpret_cast<uint32_t *>(addr);
- *p = data;
- }
-
- UHD_INLINE uint32_t _peek32(const uint32_t addr)
- {
- volatile const uint32_t *p = reinterpret_cast<const uint32_t *>(addr);
- return *p;
- }
-};
-
-global_regs::sptr global_regs::make(const size_t ctrl_base)
-{
- return sptr(new global_regs_local_impl(ctrl_base));
-}
-
-class global_regs_zc_impl : public global_regs
-{
-public:
- global_regs_zc_impl(uhd::transport::zero_copy_if::sptr xport) : _xport(xport)
- {
- }
-
- virtual ~global_regs_zc_impl(void)
- {
- }
-
- uint32_t peek32(const uhd::wb_iface::wb_addr_type addr)
- {
- global_regs_transaction_t transaction;
- transaction.is_poke = uhd::htonx<uint32_t>(0);
- transaction.addr = uhd::htonx<uint32_t>(
- static_cast<uint32_t>(addr));
- {
- uhd::transport::managed_send_buffer::sptr buff = _xport->get_send_buff(10.0);
- if (not buff or buff->size() < sizeof(transaction))
- throw std::runtime_error("global_regs_zc_impl send timeout");
- std::memcpy(buff->cast<void *>(), &transaction, sizeof(transaction));
- buff->commit(sizeof(transaction));
- }
- {
- uhd::transport::managed_recv_buffer::sptr buff = _xport->get_recv_buff(10.0);
- if (not buff or buff->size() < sizeof(transaction))
- throw std::runtime_error("global_regs_zc_impl recv timeout");
- std::memcpy(&transaction, buff->cast<const void *>(), sizeof(transaction));
- }
- return uhd::ntohx<uint32_t>(transaction.data);
- }
-
- void poke32(const uhd::wb_iface::wb_addr_type addr, const uint32_t data)
- {
- global_regs_transaction_t transaction;
- transaction.is_poke = uhd::htonx<uint32_t>(1);
- transaction.addr = uhd::htonx<uint32_t>(
- static_cast<uint32_t>(addr));
- transaction.data = uhd::htonx<uint32_t>(data);
- {
- uhd::transport::managed_send_buffer::sptr buff = _xport->get_send_buff(10.0);
- if (not buff or buff->size() < sizeof(transaction))
- throw uhd::runtime_error("global_regs_zc_impl send timeout");
- std::memcpy(buff->cast<void *>(), &transaction, sizeof(transaction));
- buff->commit(sizeof(transaction));
- }
- }
-
-private:
- uhd::transport::zero_copy_if::sptr _xport;
-};
-
-global_regs::sptr global_regs::make(uhd::transport::zero_copy_if::sptr xport)
-{
- return sptr(new global_regs_zc_impl(xport));
-}
-
-}}};
diff --git a/host/lib/usrp/e300/e300_global_regs.hpp b/host/lib/usrp/e300/e300_global_regs.hpp
deleted file mode 100644
index e7d668d78..000000000
--- a/host/lib/usrp/e300/e300_global_regs.hpp
+++ /dev/null
@@ -1,71 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_E300_GLOBAL_REGS_HPP
-#define INCLUDED_E300_GLOBAL_REGS_HPP
-
-#include <uhd/types/wb_iface.hpp>
-#include <uhd/transport/zero_copy.hpp>
-
-namespace uhd { namespace usrp { namespace e300 {
-
-struct global_regs_transaction_t {
- global_regs_transaction_t(): is_poke(0), addr(0), data(0), pad(0) {}
- uint32_t is_poke;
- uint32_t addr;
- uint32_t data;
- uint32_t pad;
-};
-
-class global_regs : uhd::noncopyable, public virtual uhd::wb_iface
-{
-public:
- typedef boost::shared_ptr<global_regs> sptr;
-
- static sptr make(const size_t ctrl_base);
- static sptr make(uhd::transport::zero_copy_if::sptr xport);
-
- static const size_t SR_CORE_READBACK = 0;
- static const size_t SR_CORE_MISC = 4;
- static const size_t SR_CORE_TEST = 28;
- static const size_t SR_CORE_XB_LOCAL = 32;
- static const size_t SR_CORE_SPI_SEL = 64;
-
- // leave some room for registers,
- // xbar starts with an offset of one
- // 1K page. A part of which is used for
- // DST_LOOKUP for DST_LOOKUP
-
- static const size_t SR_CORE_DST = 1024;
- static const size_t SR_CORE_XBAR = 2048;
-
- static const size_t RB32_CORE_MISC = 1;
- static const size_t RB32_CORE_COMPAT = 2;
- static const size_t RB32_CORE_GITHASH = 3;
- static const size_t RB32_CORE_PLL = 4;
- static const size_t RB32_CORE_NUM_CE = 8;
- static const size_t RB32_CORE_TEST = 24;
-
- // PPS selection
- static const size_t PPS_GPS = 0;
- static const size_t PPS_INT = 2;
- static const size_t PPS_EXT = 3;
-};
-
-UHD_INLINE uint32_t XB_ADDR(const uint32_t addr)
-{
- return global_regs::SR_CORE_XBAR + (addr << 2);
-}
-
-UHD_INLINE uint32_t DST_ADDR(const uint32_t addr)
-{
- return global_regs::SR_CORE_DST + (addr << 2);
-}
-
-}}};
-
-#endif /* INCLUDED_E300_GLOBAL_REGS_HPP */
diff --git a/host/lib/usrp/e300/e300_i2c.cpp b/host/lib/usrp/e300/e300_i2c.cpp
deleted file mode 100644
index 24fd429b5..000000000
--- a/host/lib/usrp/e300/e300_i2c.cpp
+++ /dev/null
@@ -1,400 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "e300_i2c.hpp"
-#include <uhd/exception.hpp>
-#include <uhd/utils/byteswap.hpp>
-#include <uhd/transport/udp_simple.hpp>
-
-#include <cstring>
-#include <chrono>
-#include <thread>
-
-namespace uhd { namespace usrp { namespace e300 {
-
-class zc_impl : public i2c
-{
-public:
- zc_impl(uhd::transport::zero_copy_if::sptr xport) : _xport(xport)
- {
- }
-
- virtual ~zc_impl(void)
- {
- }
-
- void set_i2c_reg8(
- const uint8_t addr,
- const uint8_t reg,
- const uint8_t value)
- {
- i2c_transaction_t transaction;
- transaction.type = WRITE | ONEBYTE;
- transaction.addr = addr;
- transaction.reg = uhd::htonx<uint16_t>(reg);
- transaction.data = value;
- {
- uhd::transport::managed_send_buffer::sptr buff = _xport->get_send_buff(10.0);
- if (not buff or buff->size() < sizeof(transaction))
- throw uhd::runtime_error("i2c_zc_impl send timeout");
- std::memcpy(buff->cast<void *>(), &transaction, sizeof(transaction));
- buff->commit(sizeof(transaction));
- }
- }
-
- uint8_t get_i2c_reg8(
- const uint8_t addr,
- const uint8_t reg)
- {
- i2c_transaction_t transaction;
- transaction.type = READ | ONEBYTE;
- transaction.addr = addr;
- transaction.reg = uhd::htonx<uint16_t>(reg);
- {
- uhd::transport::managed_send_buffer::sptr buff = _xport->get_send_buff(10.0);
- if (not buff or buff->size() < sizeof(transaction))
- throw std::runtime_error("i2c_zc_impl send timeout");
- std::memcpy(buff->cast<void *>(), &transaction, sizeof(transaction));
- buff->commit(sizeof(transaction));
- }
- {
- uhd::transport::managed_recv_buffer::sptr buff = _xport->get_recv_buff(10.0);
- if (not buff or buff->size() < sizeof(transaction))
- throw std::runtime_error("i2c_zc_impl recv timeout");
- std::memcpy(&transaction, buff->cast<const void *>(), sizeof(transaction));
- }
- return transaction.data;
- }
-
- void set_i2c_reg16(
- const uint8_t addr,
- const uint16_t reg,
- const uint8_t value)
- {
- i2c_transaction_t transaction;
- transaction.type = WRITE | TWOBYTE;
- transaction.addr = addr;
- transaction.reg = uhd::htonx<uint16_t>(reg);
- transaction.data = value;
- {
- uhd::transport::managed_send_buffer::sptr buff = _xport->get_send_buff(10.0);
- if (not buff or buff->size() < sizeof(transaction))
- throw uhd::runtime_error("i2c_zc_impl send timeout");
- std::memcpy(buff->cast<void *>(), &transaction, sizeof(transaction));
- buff->commit(sizeof(transaction));
- }
- }
-
- uint8_t get_i2c_reg16(
- const uint8_t addr,
- const uint16_t reg)
- {
- i2c_transaction_t transaction;
- transaction.type = READ | TWOBYTE;
- transaction.addr = addr;
- transaction.reg = uhd::htonx<uint16_t>(reg);
- {
- uhd::transport::managed_send_buffer::sptr buff = _xport->get_send_buff(10.0);
- if (not buff or buff->size() < sizeof(transaction))
- throw std::runtime_error("i2c_zc_impl send timeout");
- std::memcpy(buff->cast<void *>(), &transaction, sizeof(transaction));
- buff->commit(sizeof(transaction));
- }
- {
- uhd::transport::managed_recv_buffer::sptr buff = _xport->get_recv_buff(10.0);
- if (not buff or buff->size() < sizeof(transaction))
- throw std::runtime_error("i2c_zc_impl recv timeout");
- std::memcpy(&transaction, buff->cast<const void *>(), sizeof(transaction));
- }
- return transaction.data;
- }
-
-
-private:
- uhd::transport::zero_copy_if::sptr _xport;
-};
-
-i2c::sptr i2c::make_zc(uhd::transport::zero_copy_if::sptr xport)
-{
- return sptr(new zc_impl(xport));
-}
-
-class simple_udp_impl : public i2c
-{
-public:
- simple_udp_impl(const std::string &ip_addr, const std::string &port)
- {
- _xport = uhd::transport::udp_simple::make_connected(ip_addr, port);
- }
-
- virtual ~simple_udp_impl(void)
- {
- }
-
- void set_i2c_reg8(
- const uint8_t addr,
- const uint8_t reg,
- const uint8_t value)
- {
- i2c_transaction_t transaction;
- transaction.type = i2c::WRITE | ONEBYTE;
- transaction.addr = addr;
- transaction.reg = uhd::htonx<uint16_t>(reg);
- transaction.data = value;
-
- _xport->send(
- boost::asio::buffer(
- &transaction,
- sizeof(transaction)));
- }
-
- uint8_t get_i2c_reg8(
- const uint8_t addr,
- const uint8_t reg)
- {
- i2c_transaction_t transaction;
- transaction.type = i2c::READ | ONEBYTE;
- transaction.addr = addr;
- transaction.reg = uhd::htonx<uint16_t>(reg);
- transaction.data = 0;
-
- _xport->send(
- boost::asio::buffer(
- &transaction,
- sizeof(transaction)));
-
- uint8_t buff[sizeof(i2c_transaction_t)] = {};
- const size_t nbytes = _xport->recv(
- boost::asio::buffer(buff), 0.100);
- if (not (nbytes == sizeof(transaction)))
- throw std::runtime_error("i2c_simple_udp_impl recv timeout");
- i2c_transaction_t *reply = reinterpret_cast<i2c_transaction_t*>(buff);
- return reply->data;
- }
-
- void set_i2c_reg16(
- const uint8_t addr,
- const uint16_t reg,
- const uint8_t value)
- {
- i2c_transaction_t transaction;
- transaction.type = i2c::WRITE | TWOBYTE;
- transaction.addr = addr;
- transaction.reg = uhd::htonx<uint16_t>(reg);
- transaction.data = value;
-
- _xport->send(
- boost::asio::buffer(
- &transaction,
- sizeof(transaction)));
- }
-
- uint8_t get_i2c_reg16(
- const uint8_t addr,
- const uint16_t reg)
- {
- i2c_transaction_t transaction;
- transaction.type = i2c::READ | TWOBYTE;
- transaction.addr = addr;
- transaction.reg = uhd::htonx<uint16_t>(reg);
- transaction.data = 0;
-
- _xport->send(
- boost::asio::buffer(
- &transaction,
- sizeof(transaction)));
-
- uint8_t buff[sizeof(i2c_transaction_t)] = {};
- const size_t nbytes = _xport->recv(
- boost::asio::buffer(buff), 0.100);
- if (not (nbytes == sizeof(transaction)))
- throw std::runtime_error("i2c_simple_udp_impl recv timeout");
- i2c_transaction_t *reply = reinterpret_cast<i2c_transaction_t*>(buff);
- return reply->data;
- }
-
-private:
- uhd::transport::udp_simple::sptr _xport;
-};
-
-i2c::sptr i2c::make_simple_udp(
- const std::string &ip_addr,
- const std::string &port)
-{
- return sptr(new simple_udp_impl(ip_addr,port));
-}
-
-}}} // namespace
-
-#ifdef E300_NATIVE
-
-#include <linux/i2c.h>
-#include <linux/i2c-dev.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-
-#include <boost/thread.hpp>
-#include <stdint.h>
-
-namespace uhd { namespace usrp { namespace e300 {
-
-class i2cdev_impl : public i2c
-{
-public:
- i2cdev_impl(const std::string &device)
- {
- _fd = ::open(device.c_str(), O_RDWR);
- if (_fd < 0)
- throw uhd::system_error("open failed.");
- }
-
- virtual ~i2cdev_impl(void)
- {
- close(_fd);
- }
-
- void set_i2c_reg8(
- const uint8_t addr,
- const uint8_t reg,
- const uint8_t value)
- {
- uint8_t outbuf[2];
- i2c_rdwr_ioctl_data packets;
- i2c_msg messages[1];
-
- messages[0].addr = addr;
- messages[0].flags = 0;
- messages[0].len = sizeof(outbuf);
- messages[0].buf = outbuf;
-
- outbuf[0] = reg;
- outbuf[1] = value;
-
- packets.msgs = messages;
- packets.nmsgs = 1;
-
- if(::ioctl(_fd, I2C_RDWR, &packets) < 0) {
- throw std::runtime_error("ioctl failed");
- }
- // this is ugly
- std::this_thread::sleep_for(std::chrono::milliseconds(5));
- }
-
- uint8_t get_i2c_reg8(
- const uint8_t addr,
- const uint8_t reg)
- {
- i2c_rdwr_ioctl_data packets;
- i2c_msg messages[2];
-
- uint8_t outbuf = reg;
- messages[0].addr = addr;
- messages[0].flags = 0;
- messages[0].len = sizeof(outbuf);
- messages[0].buf = &outbuf;
-
- uint8_t inbuf;
- messages[1].addr = addr;
- messages[1].flags = I2C_M_RD;
- messages[1].len = sizeof(inbuf);
- messages[1].buf = &inbuf;
-
- packets.msgs = messages;
- packets.nmsgs = 2;
-
- if(::ioctl(_fd, I2C_RDWR, &packets) < 0) {
- throw std::runtime_error("ioctl failed.");
- }
-
- return inbuf;
- }
-
- // the daughterboard uses 16 bit addresses
- void set_i2c_reg16(
- const uint8_t addr,
- const uint16_t reg,
- const uint8_t value)
- {
- uint8_t outbuf[3];
- i2c_rdwr_ioctl_data packets;
- i2c_msg messages[1];
-
- messages[0].addr = addr;
- messages[0].flags = 0;
- messages[0].len = sizeof(outbuf);
- messages[0].buf = outbuf;
-
- outbuf[0] = (reg >> 8) & 0xff;
- outbuf[1] = reg & 0xff;
- outbuf[2] = value;
-
- packets.msgs = messages;
- packets.nmsgs = 1;
-
- if(::ioctl(_fd, I2C_RDWR, &packets) < 0) {
- throw std::runtime_error("ioctl failed");
- }
- // this is ugly
- std::this_thread::sleep_for(std::chrono::milliseconds(5));
- }
-
-
- // the daughterboard eeprom uses 16 bit addresses
- uint8_t get_i2c_reg16(
- const uint8_t addr,
- const uint16_t reg)
- {
- i2c_rdwr_ioctl_data packets;
- i2c_msg messages[2];
-
- // always little endian
- uint8_t outbuf[2];
- outbuf[0] = (reg >> 8) & 0xff;
- outbuf[1] = reg & 0xff;
-
- messages[0].addr = addr;
- messages[0].flags = 0;
- messages[0].len = sizeof(outbuf);
- messages[0].buf = outbuf;
-
- uint8_t inbuf;
- messages[1].addr = addr;
- messages[1].flags = I2C_M_RD;
- messages[1].len = sizeof(inbuf);
- messages[1].buf = &inbuf;
-
- packets.msgs = messages;
- packets.nmsgs = 2;
-
- if(::ioctl(_fd, I2C_RDWR, &packets) < 0) {
- throw std::runtime_error("ioctl failed.");
- }
-
- return inbuf;
- }
-
-private:
- int _fd;
-};
-
-}}} // namespace
-
-using namespace uhd::usrp::e300;
-
-i2c::sptr i2c::make_i2cdev(const std::string &device)
-{
- return sptr(new i2cdev_impl(device));
-}
-#else
-using namespace uhd::usrp::e300;
-
-i2c::sptr i2c::make_i2cdev(const std::string &)
-{
- throw uhd::assertion_error("i2c::make() !E300_NATIVE");
-}
-#endif // E300_NATIVE
diff --git a/host/lib/usrp/e300/e300_i2c.hpp b/host/lib/usrp/e300/e300_i2c.hpp
deleted file mode 100644
index 1606d2146..000000000
--- a/host/lib/usrp/e300/e300_i2c.hpp
+++ /dev/null
@@ -1,68 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_E300_I2C_HPP
-#define INCLUDED_E300_I2C_HPP
-
-#include <uhd/utils/noncopyable.hpp>
-#include <stdint.h>
-#include <boost/shared_ptr.hpp>
-
-#include <uhd/transport/zero_copy.hpp>
-
-namespace uhd { namespace usrp { namespace e300 {
-
-struct i2c_transaction_t {
- i2c_transaction_t(): reg(0), addr(0), data(0), type(0) {};
- uint16_t reg;
- uint8_t addr;
- uint8_t data;
- uint8_t type;
-};
-
-class i2c : public uhd::noncopyable
-{
-public:
- typedef boost::shared_ptr<i2c> sptr;
-
- static sptr make_i2cdev(const std::string &device);
- static sptr make_zc(uhd::transport::zero_copy_if::sptr xport);
- static sptr make_simple_udp(
- const std::string &ip_addr,
- const std::string &port);
-
- virtual uint8_t get_i2c_reg8(
- const uint8_t addr,
- const uint8_t reg) = 0;
-
- virtual uint8_t get_i2c_reg16(
- const uint8_t addr,
- const uint16_t reg) = 0;
-
- virtual void set_i2c_reg8(
- const uint8_t addr,
- const uint8_t reg,
- const uint8_t value) = 0;
-
- virtual void set_i2c_reg16(
- const uint8_t addr,
- const uint16_t reg,
- const uint8_t value) = 0;
-
-
- static const uint8_t DB_EEPROM_ADDR = 0x50;
- static const uint8_t MB_EEPROM_ADDR = 0x51;
-
- static const uint8_t WRITE = 0x1;
- static const uint8_t READ = 0x0;
- static const uint8_t TWOBYTE = 0x4;
- static const uint8_t ONEBYTE = 0x2;
-};
-
-}}};
-
-#endif // INCLUDED_E300_I2C_HPP
diff --git a/host/lib/usrp/e300/e300_impl.cpp b/host/lib/usrp/e300/e300_impl.cpp
deleted file mode 100644
index 59a8cec88..000000000
--- a/host/lib/usrp/e300/e300_impl.cpp
+++ /dev/null
@@ -1,749 +0,0 @@
-//
-// Copyright 2013-2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "e300_impl.hpp"
-#include "e300_defaults.hpp"
-#include "e300_fpga_defs.hpp"
-#include "e300_spi.hpp"
-#include "e300_regs.hpp"
-#include "e300_eeprom_manager.hpp"
-#include "e300_sensor_manager.hpp"
-#include "e300_common.hpp"
-#include "e300_remote_codec_ctrl.hpp"
-#include "e3xx_radio_ctrl_impl.hpp"
-
-
-#include <uhd/utils/log.hpp>
-#include <uhd/utils/static.hpp>
-#include <uhd/utils/paths.hpp>
-#include <uhd/usrp/dboard_eeprom.hpp>
-#include <uhd/transport/if_addrs.hpp>
-#include <uhd/transport/udp_zero_copy.hpp>
-#include <uhd/transport/udp_simple.hpp>
-#include <uhd/types/sensors.hpp>
-#include <boost/make_shared.hpp>
-#include <boost/algorithm/string.hpp>
-#include <boost/format.hpp>
-#include <boost/filesystem.hpp>
-#include <boost/functional/hash.hpp>
-#include <boost/bind.hpp>
-#include <boost/make_shared.hpp>
-#include <boost/assign/list_of.hpp>
-#include <boost/thread/thread.hpp> //sleep
-#include <boost/asio.hpp>
-#include <fstream>
-
-using namespace uhd;
-using namespace uhd::usrp;
-using namespace uhd::usrp::gpio_atr;
-using namespace uhd::transport;
-namespace fs = boost::filesystem;
-namespace asio = boost::asio;
-
-namespace uhd { namespace usrp { namespace e300 {
-
-/***********************************************************************
- * Discovery
- **********************************************************************/
-
-static std::vector<std::string> discover_ip_addrs(
- const std::string& addr_hint, const std::string& port)
-{
- std::vector<std::string> addrs;
-
- // Create a UDP transport to communicate:
- // Some devices will cause a throw when opened for a broadcast address.
- // We print and recover so the caller can loop through all bcast addrs.
- uhd::transport::udp_simple::sptr udp_bcast_xport;
- try {
- udp_bcast_xport = uhd::transport::udp_simple::make_broadcast(addr_hint, port);
- } catch(const std::exception &e) {
- UHD_LOGGER_ERROR("E300") << boost::format("Cannot open UDP transport on %s for discovery%s")
- % addr_hint % e.what() ;
- return addrs;
- } catch(...) {
- UHD_LOGGER_ERROR("E300") << "E300 Network discovery unknown error";
- return addrs;
- }
-
- // TODO: Do not abuse the I2C transport here ...
- // we send a read request to i2c address 0x51,
- // to read register 0
- i2c_transaction_t req;
- req.type = i2c::READ | i2c::ONEBYTE;
- req.addr = 0x51; // mboard's eeprom address, we don't really care
- req.reg = 4;
-
- // send dummy request
- try {
- udp_bcast_xport->send(boost::asio::buffer(&req, sizeof(req)));
- } catch (const std::exception &ex) {
- UHD_LOGGER_ERROR("E300") << "E300 Network discovery error " << ex.what();
- return addrs;
- } catch(...) {
- UHD_LOGGER_ERROR("E300") << "E300 Network discovery unknown error";
- return addrs;
- }
-
- // loop for replies until timeout
- while (true) {
- uint8_t buff[sizeof(i2c_transaction_t)] = {};
- const size_t nbytes = udp_bcast_xport->recv(boost::asio::buffer(buff), 0.050);
- if (nbytes == 0)
- break; //No more responses
-
- const i2c_transaction_t *reply = reinterpret_cast<const i2c_transaction_t*>(buff);
- if (req.addr == reply->addr)
- addrs.push_back(udp_bcast_xport->get_recv_addr());
- }
-
- return addrs;
-}
-
-static bool is_loopback(const if_addrs_t &if_addrs)
-{
- return if_addrs.inet == asio::ip::address_v4::loopback().to_string();
-}
-
-device_addrs_t e300_find(const device_addr_t &multi_dev_hint)
-{
- // handle multi device discovery
- device_addrs_t hints = separate_device_addr(multi_dev_hint);
-
- if (hints.size() > 1) {
- device_addrs_t found_devices;
- std::string err_msg;
- BOOST_FOREACH(const device_addr_t &hint_i, hints)
- {
- device_addrs_t found_devices_i = e300_find(hint_i);
- if(found_devices_i.size() != 1)
- err_msg += str(boost::format(
- "Could not resolve device hint \"%s\" to a single device.")
- % hint_i.to_string());
- else
- found_devices.push_back(found_devices_i[0]);
- if (found_devices.empty())
- return device_addrs_t();
-
- if (not err_msg.empty())
- throw uhd::value_error(err_msg);
- }
- return device_addrs_t(1, combine_device_addrs(found_devices));
- }
-
- // initialize the hint for a single device case
- UHD_ASSERT_THROW(hints.size() <= 1);
- hints.resize(1); // in case it was empty
- device_addr_t hint = hints[0];
- device_addrs_t e300_addrs;
-
- // return an empty list of addresses when type is set to non-e300
- if (hint.has_key("type") and hint["type"] != "e3x0")
- return e300_addrs;
-
- const bool loopback_only =
- get_if_addrs().size() == 1 and is_loopback(get_if_addrs().at(0));
-
- // if we don't have connectivity, we might as well skip the network part
- if (not loopback_only) {
- // if no address or node has been specified, send a broadcast
- if ((not hint.has_key("addr")) and (not hint.has_key("node"))) {
- BOOST_FOREACH(const if_addrs_t &if_addrs, get_if_addrs())
- {
- // avoid the loopback device
- if (is_loopback(if_addrs))
- continue;
-
- // create a new hint with this broadcast address
- device_addr_t new_hint = hint;
- new_hint["addr"] = if_addrs.bcast;
-
- // call discover with the new hint and append results
- device_addrs_t new_e300_addrs = e300_find(new_hint);
- e300_addrs.insert(e300_addrs.begin(),
- new_e300_addrs.begin(), new_e300_addrs.end());
-
- }
- return e300_addrs;
- }
-
- std::vector<std::string> ip_addrs = discover_ip_addrs(
- hint["addr"], E300_SERVER_I2C_PORT);
-
- BOOST_FOREACH(const std::string &ip_addr, ip_addrs)
- {
- device_addr_t new_addr;
- new_addr["type"] = "e3x0";
- new_addr["addr"] = ip_addr;
-
- // see if we can read the eeprom
- try {
- e300_eeprom_manager eeprom_manager(
- i2c::make_simple_udp(new_addr["addr"], E300_SERVER_I2C_PORT));
- const mboard_eeprom_t eeprom = eeprom_manager.get_mb_eeprom();
- new_addr["name"] = eeprom["name"];
- new_addr["serial"] = eeprom["serial"];
- new_addr["product"] = eeprom_manager.get_mb_type_string();
- } catch (...) {
- // set these values as empty string, so the device may still be found
- // and the filters below can still operate on the discovered device
- new_addr["name"] = "";
- new_addr["serial"] = "";
- }
- // filter the discovered device below by matching optional keys
- if ((not hint.has_key("name") or hint["name"] == new_addr["name"]) and
- (not hint.has_key("serial") or hint["serial"] == new_addr["serial"]))
- {
- e300_addrs.push_back(new_addr);
- }
- }
- }
-
- // finally search locally
- // if device node is not provided,
- // use the default one
- if (not hint.has_key("node")) {
- device_addr_t new_addr = hint;
- new_addr["node"] = "/dev/axi_fpga";
- return e300_find(new_addr);
- }
-
- // use the given node
- if (fs::exists(hint["node"])) {
- device_addr_t new_addr;
- new_addr["type"] = "e3x0";
- new_addr["node"] = fs::system_complete(fs::path(hint["node"])).string();
-
- try {
- e300_eeprom_manager eeprom_manager(i2c::make_i2cdev(E300_I2CDEV_DEVICE));
- const mboard_eeprom_t eeprom = eeprom_manager.get_mb_eeprom();
- new_addr["name"] = eeprom["name"];
- new_addr["serial"] = eeprom["serial"];
- new_addr["product"] = eeprom_manager.get_mb_type_string();
- } catch (...) {
- // set these values as empty string, so the device may still be found
- // and the filters below can still operate on the discovered device
- new_addr["name"] = "";
- new_addr["serial"] = "";
- }
- // filter the discovered device below by matching optional keys
- if ((not hint.has_key("name") or hint["name"] == new_addr["name"]) and
- (not hint.has_key("serial") or hint["serial"] == new_addr["serial"]))
- {
- e300_addrs.push_back(new_addr);
- }
- }
-
- return e300_addrs;
-}
-
-
-/***********************************************************************
- * Make
- **********************************************************************/
-static device::sptr e300_make(const device_addr_t &device_addr)
-{
- UHD_LOGGER_DEBUG("E300")<< "e300_make with args " << device_addr.to_pp_string() ;
- if(device_addr.has_key("server"))
- throw uhd::runtime_error(
- str(boost::format("Please run the server executable \"%s\"")
- % "usrp_e3x0_network_mode"));
- else
- return device::sptr(new e300_impl(device_addr));
-}
-
-// Common code used by e300_impl and e300_image_loader
-void get_e3x0_fpga_images(const uhd::device_addr_t &device_addr,
- std::string &fpga_image,
- std::string &idle_image){
- const uint16_t pid = boost::lexical_cast<uint16_t>(
- device_addr["product"]);
-
- //extract the FPGA path for the e300
- switch(e300_eeprom_manager::get_mb_type(pid)) {
- case e300_eeprom_manager::USRP_E310_SG1_MB:
- fpga_image = device_addr.cast<std::string>("fpga",
- find_image_path(E310_SG1_FPGA_FILE_NAME));
- idle_image = find_image_path(E3XX_SG1_FPGA_IDLE_FILE_NAME);
- break;
- case e300_eeprom_manager::USRP_E310_SG3_MB:
- fpga_image = device_addr.cast<std::string>("fpga",
- find_image_path(E310_SG3_FPGA_FILE_NAME));
- idle_image = find_image_path(E3XX_SG3_FPGA_IDLE_FILE_NAME);
- break;
- case e300_eeprom_manager::USRP_E300_MB:
- fpga_image = device_addr.cast<std::string>("fpga",
- find_image_path(E300_FPGA_FILE_NAME));
- idle_image = find_image_path(E3XX_SG1_FPGA_IDLE_FILE_NAME);
- break;
- case e300_eeprom_manager::UNKNOWN:
- default:
- UHD_LOGGER_WARNING("E300") << "Unknown motherboard type, loading e300 image."
- ;
- fpga_image = device_addr.cast<std::string>("fpga",
- find_image_path(E300_FPGA_FILE_NAME));
- idle_image = find_image_path(E3XX_SG1_FPGA_IDLE_FILE_NAME);
- break;
- }
-}
-
-/***********************************************************************
- * Structors
- **********************************************************************/
-e300_impl::e300_impl(const uhd::device_addr_t &device_addr)
- : _device_addr(device_addr)
- , _xport_path(device_addr.has_key("addr") ? ETH : AXI)
- , _dma_chans_available(MAX_DMA_CHANNEL_PAIRS, ~size_t(0) /* all available at the beginning */)
-{
- stream_options.rx_fc_request_freq = E300_RX_FC_REQUEST_FREQ;
-
- ////////////////////////////////////////////////////////////////////
- // load the fpga image
- ////////////////////////////////////////////////////////////////////
- if (_xport_path == AXI) {
- _do_not_reload = device_addr.has_key("no_reload_fpga");
- if (not _do_not_reload) {
- std::string fpga_image;
-
- // need to re-read product ID code because of conversion into string in find function
- e300_eeprom_manager eeprom_manager(i2c::make_i2cdev(E300_I2CDEV_DEVICE));
- const mboard_eeprom_t eeprom = eeprom_manager.get_mb_eeprom();
- device_addr_t device_addr_cp(device_addr.to_string());
- device_addr_cp["product"] = eeprom["product"];
-
- get_e3x0_fpga_images(device_addr_cp,
- fpga_image,
- _idle_image);
- common::load_fpga_image(fpga_image);
- }
- }
-
- ////////////////////////////////////////////////////////////////////
- // setup fifo xports
- ////////////////////////////////////////////////////////////////////
- _ctrl_xport_params.recv_frame_size = e300::DEFAULT_CTRL_FRAME_SIZE;
- _ctrl_xport_params.num_recv_frames = e300::DEFAULT_CTRL_NUM_FRAMES;
- _ctrl_xport_params.send_frame_size = e300::DEFAULT_CTRL_FRAME_SIZE;
- _ctrl_xport_params.num_send_frames = e300::DEFAULT_CTRL_NUM_FRAMES;
-
- _data_xport_params.recv_frame_size = device_addr.cast<size_t>("recv_frame_size",
- e300::DEFAULT_RX_DATA_FRAME_SIZE);
- _data_xport_params.num_recv_frames = device_addr.cast<size_t>("num_recv_frames",
- e300::DEFAULT_RX_DATA_NUM_FRAMES);
- _data_xport_params.send_frame_size = device_addr.cast<size_t>("send_frame_size",
- e300::DEFAULT_TX_DATA_FRAME_SIZE);
- _data_xport_params.num_send_frames = device_addr.cast<size_t>("num_send_frames",
- e300::DEFAULT_TX_DATA_NUM_FRAMES);
-
-
- // until we figure out why this goes wrong we'll keep this hack around for
- // the ethernet case, in the AXI case we cannot go above one page
- if (_xport_path == ETH) {
- _data_xport_params.recv_frame_size =
- std::min(e300::MAX_NET_RX_DATA_FRAME_SIZE, _data_xport_params.recv_frame_size);
- _data_xport_params.send_frame_size =
- std::min(e300::MAX_NET_TX_DATA_FRAME_SIZE, _data_xport_params.send_frame_size);
- } else {
- _data_xport_params.recv_frame_size =
- std::min(e300::MAX_AXI_RX_DATA_FRAME_SIZE, _data_xport_params.recv_frame_size);
- _data_xport_params.send_frame_size =
- std::min(e300::MAX_AXI_TX_DATA_FRAME_SIZE, _data_xport_params.send_frame_size);
- }
- udp_zero_copy::buff_params dummy_buff_params_out;
-
- ad9361_ctrl::sptr codec_ctrl;
- if (_xport_path == ETH) {
- zero_copy_if::sptr codec_xport =
- udp_zero_copy::make(device_addr["addr"], E300_SERVER_CODEC_PORT, _ctrl_xport_params, dummy_buff_params_out, device_addr);
- codec_ctrl = e300_remote_codec_ctrl::make(codec_xport);
- zero_copy_if::sptr gregs_xport =
- udp_zero_copy::make(device_addr["addr"], E300_SERVER_GREGS_PORT, _ctrl_xport_params, dummy_buff_params_out, device_addr);
- _global_regs = global_regs::make(gregs_xport);
-
- zero_copy_if::sptr i2c_xport;
- i2c_xport = udp_zero_copy::make(device_addr["addr"], E300_SERVER_I2C_PORT, _ctrl_xport_params, dummy_buff_params_out, device_addr);
- _eeprom_manager = boost::make_shared<e300_eeprom_manager>(i2c::make_zc(i2c_xport));
-
- uhd::transport::zero_copy_xport_params sensor_xport_params;
- sensor_xport_params.recv_frame_size = 128;
- sensor_xport_params.num_recv_frames = 10;
- sensor_xport_params.send_frame_size = 128;
- sensor_xport_params.num_send_frames = 10;
-
- zero_copy_if::sptr sensors_xport;
- sensors_xport = udp_zero_copy::make(device_addr["addr"], E300_SERVER_SENSOR_PORT, sensor_xport_params, dummy_buff_params_out, device_addr);
- _sensor_manager = e300_sensor_manager::make_proxy(sensors_xport);
-
- } else {
- e300_fifo_config_t fifo_cfg;
- try {
- fifo_cfg = e300_read_sysfs();
- } catch (...) {
- throw uhd::runtime_error("Failed to get driver parameters from sysfs.");
- }
- _fifo_iface = e300_fifo_interface::make(fifo_cfg);
- _global_regs = global_regs::make(_fifo_iface->get_global_regs_base());
-
- ad9361_params::sptr client_settings = boost::make_shared<e300_ad9361_client_t>();
- codec_ctrl = ad9361_ctrl::make_spi(client_settings, spi::make(E300_SPIDEV_DEVICE), 1);
- // This is horrible ... why do I have to sleep here?
- boost::this_thread::sleep(boost::posix_time::milliseconds(100));
- _eeprom_manager = boost::make_shared<e300_eeprom_manager>(i2c::make_i2cdev(E300_I2CDEV_DEVICE));
- _sensor_manager = e300_sensor_manager::make_local(_global_regs);
- }
-
-#ifdef E300_GPSD
- UHD_LOGGER_INFO("E300") << "Detecting internal GPS ";
- try {
- if (_xport_path == AXI)
- _gps = gpsd_iface::make("localhost", 2947);
- else
- _gps = gpsd_iface::make(device_addr["addr"], 2947);
- } catch (std::exception &e) {
- UHD_LOGGER_ERROR("E300") << "An error occured making GPSDd interface: " << e.what();
- }
-
- if (_gps) {
- for (size_t i = 0; i < _GPS_TIMEOUT; i++)
- {
- boost::this_thread::sleep(boost::posix_time::seconds(1));
- if (!_gps->gps_detected())
- std::cout << "." << std::flush;
- else {
- std::cout << ".... " << std::flush;
- break;
- }
- }
- UHD_LOGGER_INFO("E300") << "GPSDO " << (_gps->gps_detected() ? "found" : "not found");
- }
-#endif
-
- // Verify we can talk to the e300 core control registers ...
- UHD_LOGGER_INFO("E300") << "Initializing core control (global registers)..." << std::endl;
- this->_register_loopback_self_test(
- _global_regs,
- global_regs::SR_CORE_TEST,
- global_regs::RB32_CORE_TEST
- );
-
- // Verify fpga compatibility version matches at least for the major
- if (_get_version(FPGA_MAJOR) != fpga::COMPAT_MAJOR) {
- throw uhd::runtime_error(str(boost::format(
- "Expected FPGA compatibility number %lu.x, but got %lu.%lu:\n"
- "The FPGA build is not compatible with the host code build.\n"
- "%s"
- ) % fpga::COMPAT_MAJOR
- % _get_version(FPGA_MAJOR) % _get_version(FPGA_MINOR)
- % print_utility_error("uhd_images_downloader.py")));
- }
-
- ////////////////////////////////////////////////////////////////////
- // Initialize the properties tree
- ////////////////////////////////////////////////////////////////////
- _tree->create<std::string>("/name").set("E-Series Device");
- const fs_path mb_path = "/mboards/0";
- _tree->create<std::string>(mb_path / "name")
- .set(_eeprom_manager->get_mb_type_string());
-
- _tree->create<std::string>(mb_path / "codename").set("Troll");
-
- _tree->create<std::string>(mb_path / "fpga_version").set(
- str(boost::format("%u.%u")
- % _get_version(FPGA_MAJOR)
- % _get_version(FPGA_MINOR)));
-
- _tree->create<std::string>(mb_path / "fpga_version_hash").set(
- _get_version_hash());
-
- // Clock reference source
- _tree->create<std::string>(mb_path / "clock_source" / "value")
- .add_coerced_subscriber(boost::bind(&e300_impl::_update_clock_source, this, _1))
- .set(e300::DEFAULT_CLOCK_SRC);
- static const std::vector<std::string> clock_sources =
- boost::assign::list_of("internal"); //external,gpsdo not supported
- _tree->create<std::vector<std::string> >(mb_path / "clock_source" / "options").set(clock_sources);
-
- ////////////////////////////////////////////////////////////////////
- // and do the misc mboard sensors
- ////////////////////////////////////////////////////////////////////
- _tree->create<int>(mb_path / "sensors");
- BOOST_FOREACH(const std::string &name, _sensor_manager->get_sensors())
- {
- _tree->create<sensor_value_t>(mb_path / "sensors" / name)
- .set_publisher(boost::bind(&e300_sensor_manager::get_sensor, _sensor_manager, name));
- }
-#ifdef E300_GPSD
- if (_gps) {
- BOOST_FOREACH(const std::string &name, _gps->get_sensors())
- {
- _tree->create<sensor_value_t>(mb_path / "sensors" / name)
- .set_publisher(boost::bind(&gpsd_iface::get_sensor, _gps, name));
- }
- }
-#endif
-
- ////////////////////////////////////////////////////////////////////
- // setup the mboard eeprom
- ////////////////////////////////////////////////////////////////////
- _tree->create<mboard_eeprom_t>(mb_path / "eeprom")
- .set(_eeprom_manager->get_mb_eeprom()) // set first...
- .add_coerced_subscriber(boost::bind(
- &e300_eeprom_manager::write_mb_eeprom,
- _eeprom_manager, _1));
-
- ////////////////////////////////////////////////////////////////////
- // dboard eeproms but not really
- ////////////////////////////////////////////////////////////////////
- dboard_eeprom_t db_eeprom;
- _tree->create<dboard_eeprom_t>(mb_path / "dboards" / "A" / "rx_eeprom")
- .set(_eeprom_manager->get_db_eeprom())
- .add_coerced_subscriber(boost::bind(
- &e300_eeprom_manager::write_db_eeprom,
- _eeprom_manager, _1));
-
- _tree->create<dboard_eeprom_t>(mb_path / "dboards" / "A" / "tx_eeprom")
- .set(_eeprom_manager->get_db_eeprom())
- .add_coerced_subscriber(boost::bind(
- &e300_eeprom_manager::write_db_eeprom,
- _eeprom_manager, _1));
-
- _tree->create<dboard_eeprom_t>(mb_path / "dboards" / "A" / "gdb_eeprom").set(db_eeprom);
-
- ////////////////////////////////////////////////////////////////////
- // Access to global regs
- ////////////////////////////////////////////////////////////////////
- _tree->create<uint32_t>(mb_path / "global_regs" / "misc")
- .add_coerced_subscriber(boost::bind(&global_regs::poke32, _global_regs, global_regs::SR_CORE_MISC, _1))
- ;
- _tree->create<uint32_t>(mb_path / "global_regs" / "pll")
- .set_publisher(boost::bind(&global_regs::peek32, _global_regs, global_regs::RB32_CORE_PLL))
- ;
-
- ////////////////////////////////////////////////////////////////////
- // clocking
- ////////////////////////////////////////////////////////////////////
- _tree->create<double>(mb_path / "tick_rate")
- .add_coerced_subscriber(boost::bind(&device3_impl::update_tx_streamers, this, _1))
- .add_coerced_subscriber(boost::bind(&device3_impl::update_rx_streamers, this, _1))
- ;
-
- //default some chains on -- needed for setup purposes
- UHD_LOGGER_DEBUG("E300") << "Initializing AD9361 using hard SPI core..." << std::flush;
- codec_ctrl->set_active_chains(true, false, true, false);
- codec_ctrl->set_clock_rate(50e6);
- UHD_LOGGER_DEBUG("E300") << "OK" << std::endl;
-
- ////////////////////////////////////////////////////////////////////
- // Set up RFNoC blocks
- ////////////////////////////////////////////////////////////////////
- const size_t n_rfnoc_blocks = _global_regs->peek32(global_regs::RB32_CORE_NUM_CE);
- enumerate_rfnoc_blocks(
- 0, /* mboard index */
- n_rfnoc_blocks,
- E300_XB_DST_AXI + 1, /* base port, rfnoc blocks come after the AXI connect */
- uhd::sid_t(E300_DEVICE_HERE, 0, E300_DEVICE_THERE, 0),
- device_addr_t()
- );
-
- // If we have a radio, we must configure its codec control:
- std::vector<rfnoc::block_id_t> radio_ids = find_blocks<rfnoc::e3xx_radio_ctrl_impl>("Radio");
- if (radio_ids.size() > 0) {
- UHD_LOGGER_DEBUG("E300") << "Initializing Radio Block..." << std::endl;
- get_block_ctrl<rfnoc::e3xx_radio_ctrl_impl>(radio_ids[0])->setup_radio(codec_ctrl);
- if (radio_ids.size() != 1) {
- UHD_LOGGER_WARNING("E300") << "Too many Radio Blocks found. Using only " << radio_ids[0] << std::endl;
- }
- } else {
- UHD_LOGGER_DEBUG("E300") << "No Radio Block found. Assuming radio-less operation." << std::endl;
- }
-
- ////////////////////////////////////////////////////////////////////
- // do some post-init tasks
- ////////////////////////////////////////////////////////////////////
- // init the clock rate to something reasonable
- _tree->access<double>(mb_path / "tick_rate")
- .set(device_addr.cast<double>("master_clock_rate", ad936x_manager::DEFAULT_TICK_RATE));
-
- // subdev spec contains full width of selections
- subdev_spec_t rx_spec, tx_spec;
- BOOST_FOREACH(const std::string &fe, _tree->list(mb_path / "dboards" / "A" / "rx_frontends"))
- {
- rx_spec.push_back(subdev_spec_pair_t("A", fe));
- }
- BOOST_FOREACH(const std::string &fe, _tree->list(mb_path / "dboards" / "A" / "tx_frontends"))
- {
- tx_spec.push_back(subdev_spec_pair_t("A", fe));
- }
- _tree->create<subdev_spec_t>(mb_path / "rx_subdev_spec").set(rx_spec);
- _tree->create<subdev_spec_t>(mb_path / "tx_subdev_spec").set(tx_spec);
- UHD_LOGGER_DEBUG("E300") << "end of e300_impl()" << std::endl;
-}
-
-e300_impl::~e300_impl(void)
-{
- // Force RFNoC destructors to fire before loading the idle image
- _rfnoc_block_ctrl.clear();
- if (_xport_path == AXI and not _do_not_reload)
- common::load_fpga_image(_idle_image);
-}
-
-void e300_impl::_register_loopback_self_test(wb_iface::sptr iface, uint32_t w_addr, uint32_t r_addr)
-{
- bool test_fail = false;
- UHD_LOGGER_INFO("E300") << "Performing register loopback test... ";
- size_t hash = size_t(time(NULL));
- for (size_t i = 0; i < 100; i++)
- {
- boost::hash_combine(hash, i);
- iface->poke32(w_addr, uint32_t(hash));
- test_fail = iface->peek32(r_addr) != uint32_t(hash);
- if (test_fail) break; //exit loop on any failure
- }
- UHD_LOGGER_INFO("E300") << "Register loopback test " << ((test_fail)? " failed" : "passed");
-}
-
-uint32_t e300_impl::_get_version(compat_t which)
-{
- const uint16_t compat_num
- = _global_regs->peek32(global_regs::RB32_CORE_COMPAT);
-
- switch(which) {
- case FPGA_MINOR:
- return compat_num & 0xff;
- case FPGA_MAJOR:
- return (compat_num & 0xff00) >> 8;
- default:
- throw uhd::value_error("Requested unknown version.");
- };
-}
-
-std::string e300_impl::_get_version_hash(void)
-{
- const uint32_t git_hash
- = _global_regs->peek32(global_regs::RB32_CORE_GITHASH);
- return str(boost::format("%7x%s")
- % (git_hash & 0x0FFFFFFF)
- % ((git_hash & 0xF0000000) ? "-dirty" : ""));
-}
-
-
-void e300_impl::_setup_dest_mapping(
- const uhd::sid_t &sid,
- const size_t which_stream)
-{
- UHD_LOGGER_DEBUG("E300") << boost::format("[E300] Setting up dest map for host ep %lu to be stream %d")
- % sid.get_src_endpoint() % which_stream << std::endl;
- _global_regs->poke32(DST_ADDR(sid.get_src_endpoint()), which_stream);
-}
-
-size_t e300_impl::_get_axi_dma_channel_pair()
-{
- if (_dma_chans_available.none()) {
- throw uhd::runtime_error("No more free DMA channels available.");
- }
-
- size_t first_free_pair = _dma_chans_available.find_first();
- _dma_chans_available.reset(first_free_pair);
- return first_free_pair;
-}
-
-uint16_t e300_impl::_get_udp_port(
- uint8_t destination,
- uint8_t prefix)
-{
- if (destination == E300_XB_DST_RADIO) {
- if (prefix == E300_RADIO_DEST_PREFIX_CTRL)
- return boost::lexical_cast<uint16_t>(E300_SERVER_CTRL_PORT0);
- else if (prefix == E300_RADIO_DEST_PREFIX_TX)
- return boost::lexical_cast<uint16_t>(E300_SERVER_TX_PORT0);
- else if (prefix == E300_RADIO_DEST_PREFIX_RX)
- return boost::lexical_cast<uint16_t>(E300_SERVER_RX_PORT0);
- } else if (destination == E300_XB_DST_R1) {
- if (prefix == E300_RADIO_DEST_PREFIX_CTRL)
- return boost::lexical_cast<uint16_t>(E300_SERVER_CTRL_PORT1);
- else if (prefix == E300_RADIO_DEST_PREFIX_TX)
- return boost::lexical_cast<uint16_t>(E300_SERVER_TX_PORT1);
- else if (prefix == E300_RADIO_DEST_PREFIX_RX)
- return boost::lexical_cast<uint16_t>(E300_SERVER_RX_PORT1);
- }
- throw uhd::value_error(str(boost::format("No UDP port defined for combination: %u %u") % destination % prefix));
-}
-
-uhd::sid_t e300_impl::_allocate_sid(
- const uhd::sid_t &address)
-{
- uhd::sid_t sid = address;
- sid.set_src_addr(E300_DEVICE_HERE);
- sid.set_src_endpoint(_sid_framer);
-
- // TODO: We don't have to do this everytime ...
- // Program the E300 to recognize it's own local address.
- _global_regs->poke32(global_regs::SR_CORE_XB_LOCAL, address.get_dst_addr());
-
- // Program CAM entry for outgoing packets matching a E300 resource
- // (e.g. Radio).
- // This type of packet matches the XB_LOCAL address and is looked up in
- // the upper half of the CAM
- _global_regs->poke32(XB_ADDR(256 + address.get_dst_endpoint()), address.get_dst_xbarport());
-
- // TODO: We don't have to do this everytime ...
- // Program CAM entry for returning packets to us
- // (for example host via zynq_fifo)
- // This type of packet does not match the XB_LOCAL address and is
- // looked up in the lower half of the CAM
- _global_regs->poke32(XB_ADDR(E300_DEVICE_HERE), E300_XB_DST_AXI);
-
- // increment for next setup
- _sid_framer++;
-
- return sid;
-}
-
-uhd::both_xports_t e300_impl::make_transport(
- const uhd::sid_t &address,
- const xport_type_t type,
- const uhd::device_addr_t &)
-{
- uhd::both_xports_t xports;
- xports.endianness = ENDIANNESS_LITTLE;
-
- const uhd::transport::zero_copy_xport_params params =
- (type == CTRL) ? _ctrl_xport_params : _data_xport_params;
-
- xports.send_sid = _allocate_sid(address);
- xports.recv_sid = xports.send_sid.reversed();
- xports.recv_buff_size = params.recv_frame_size * params.num_recv_frames;
- xports.send_buff_size = params.send_frame_size * params.num_send_frames;
-
- if (_xport_path != AXI) {
- throw uhd::runtime_error("[E300] Currently only AXI transport supported with RFNOC");
- }
-
- const size_t chan_pair = _get_axi_dma_channel_pair();
- xports.send = _fifo_iface->make_send_xport(chan_pair, params);
- xports.recv = _fifo_iface->make_recv_xport(chan_pair, params);
- _setup_dest_mapping(xports.send_sid, chan_pair);
-
- return xports;
-}
-
-void e300_impl::_update_clock_source(const std::string &source)
-{
- if (source != "internal") {
- throw uhd::value_error(boost::str(
- boost::format("Clock source option not supported: %s. The only value supported is \"internal\". " \
- "To discipline the internal oscillator, set the appropriate time source.") % source
- ));
- }
-}
-
-}}} // namespace
-
-UHD_STATIC_BLOCK(register_e300_device)
-{
- device::register_device(&uhd::usrp::e300::e300_find, &uhd::usrp::e300::e300_make, uhd::device::USRP);
-}
diff --git a/host/lib/usrp/e300/e300_impl.hpp b/host/lib/usrp/e300/e300_impl.hpp
deleted file mode 100644
index 2e919cf9b..000000000
--- a/host/lib/usrp/e300/e300_impl.hpp
+++ /dev/null
@@ -1,195 +0,0 @@
-//
-// Copyright 2013-2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_E300_IMPL_HPP
-#define INCLUDED_E300_IMPL_HPP
-
-#include "../device3/device3_impl.hpp"
-#include <uhd/property_tree.hpp>
-#include <uhd/usrp/mboard_eeprom.hpp>
-#include <uhd/usrp/dboard_eeprom.hpp>
-#include <uhd/usrp/subdev_spec.hpp>
-#include <uhd/types/serial.hpp>
-#include <uhd/types/sensors.hpp>
-
-#include <boost/weak_ptr.hpp>
-#include <boost/thread/mutex.hpp>
-#include <boost/dynamic_bitset.hpp>
-#include <string>
-#include "e300_fifo_config.hpp"
-
-#include "e300_global_regs.hpp"
-#include "e300_i2c.hpp"
-#include "e300_eeprom_manager.hpp"
-#include "e300_sensor_manager.hpp"
-
-/* if we don't compile with gpsd support, don't bother */
-#ifdef E300_GPSD
-#include "gpsd_iface.hpp"
-#endif
-
-#include <atomic>
-
-namespace uhd { namespace usrp { namespace e300 {
-
-static const std::string E300_FPGA_FILE_NAME = "usrp_e300_fpga.bit";
-static const std::string E310_SG1_FPGA_FILE_NAME = "usrp_e310_fpga.bit";
-static const std::string E310_SG3_FPGA_FILE_NAME = "usrp_e310_fpga_sg3.bit";
-
-static const std::string E3XX_SG1_FPGA_IDLE_FILE_NAME = "usrp_e3xx_fpga_idle.bit";
-static const std::string E3XX_SG3_FPGA_IDLE_FILE_NAME = "usrp_e3xx_fpga_idle_sg3.bit";
-
-static const std::string E300_TEMP_SYSFS = "iio:device0";
-static const std::string E300_SPIDEV_DEVICE = "/dev/spidev0.1";
-static const std::string E300_I2CDEV_DEVICE = "/dev/i2c-0";
-
-static std::string E300_SERVER_RX_PORT0 = "21756";
-static std::string E300_SERVER_TX_PORT0 = "21757";
-static std::string E300_SERVER_CTRL_PORT0 = "21758";
-
-static std::string E300_SERVER_RX_PORT1 = "21856";
-static std::string E300_SERVER_TX_PORT1 = "21857";
-static std::string E300_SERVER_CTRL_PORT1 = "21858";
-
-
-static std::string E300_SERVER_CODEC_PORT = "21759";
-static std::string E300_SERVER_GREGS_PORT = "21760";
-static std::string E300_SERVER_I2C_PORT = "21761";
-static std::string E300_SERVER_SENSOR_PORT = "21762";
-
-static const double E300_RX_SW_BUFF_FULLNESS = 0.9; //Buffer should be half full
-static const size_t E300_RX_FC_REQUEST_FREQ = 5; // per flow ctrl window
-static const size_t E300_TX_FC_RESPONSE_FREQ = 8; // per flow ctrl window
-
-// crossbar settings
-static const uint8_t E300_RADIO_DEST_PREFIX_TX = 0;
-static const uint8_t E300_RADIO_DEST_PREFIX_CTRL = 1;
-static const uint8_t E300_RADIO_DEST_PREFIX_RX = 2;
-
-static const uint8_t E300_XB_DST_AXI = 0;
-static const uint8_t E300_XB_DST_RADIO = 1;
-static const uint8_t E300_XB_DST_R1 = 2;
-// RFNoC blocks are connected to the first port
-// after the last radio (there might be less than 2
-// radios).
-
-static const uint8_t E300_DEVICE_THERE = 2;
-static const uint8_t E300_DEVICE_HERE = 0;
-
-static const size_t E300_R0_CTRL_STREAM = (0 << 2) | E300_RADIO_DEST_PREFIX_CTRL;
-static const size_t E300_R0_TX_DATA_STREAM = (0 << 2) | E300_RADIO_DEST_PREFIX_TX;
-static const size_t E300_R0_RX_DATA_STREAM = (0 << 2) | E300_RADIO_DEST_PREFIX_RX;
-
-static const size_t E300_R1_CTRL_STREAM = (1 << 2) | E300_RADIO_DEST_PREFIX_CTRL;
-static const size_t E300_R1_TX_DATA_STREAM = (1 << 2) | E300_RADIO_DEST_PREFIX_TX;
-static const size_t E300_R1_RX_DATA_STREAM = (1 << 2) | E300_RADIO_DEST_PREFIX_RX;
-
-uhd::device_addrs_t e300_find(const uhd::device_addr_t &multi_dev_hint);
-void get_e3x0_fpga_images(const uhd::device_addr_t &device_args,
- std::string &fpga_image,
- std::string &idle_image);
-
-/*!
- * USRP-E300 implementation guts:
- * The implementation details are encapsulated here.
- * Handles properties on the mboard, dboard, dsps...
- */
-class e300_impl : public uhd::usrp::device3_impl
-{
-public:
- /************************************************************************
- * Structors
- ***********************************************************************/
- e300_impl(const uhd::device_addr_t &);
- virtual ~e300_impl(void);
-
-private: // types
- enum compat_t {FPGA_MAJOR, FPGA_MINOR};
-
-protected: // methods
- /************************************************************************
- * Legacy device3 stuff
- ***********************************************************************/
- void subdev_to_blockid(
- const uhd::usrp::subdev_spec_pair_t &spec, const size_t mb_i,
- rfnoc::block_id_t &block_id, uhd::device_addr_t &block_args
- );
- uhd::usrp::subdev_spec_pair_t blockid_to_subdev(
- const rfnoc::block_id_t &blockid, const device_addr_t &block_args
- );
-
- /************************************************************************
- * Transport related
- ***********************************************************************/
- uhd::device_addr_t get_rx_hints(size_t);
-
-private: // methods
- /************************************************************************
- * Initialization
- ***********************************************************************/
- void _register_loopback_self_test(wb_iface::sptr iface, uint32_t w_addr, uint32_t r_addr);
-
- uint32_t _get_version(compat_t which);
- std::string _get_version_hash(void);
-
- /************************************************************************
- * Transport related
- ***********************************************************************/
- uhd::sid_t _allocate_sid(const uhd::sid_t &address);
-
- void _setup_dest_mapping(
- const uhd::sid_t &sid,
- const size_t which_stream);
-
- /*! Return the first free AXI channel pair.
- *
- * \throws uhd::runtime_error if no free channel pairs are available.
- */
- size_t _get_axi_dma_channel_pair();
-
- // For network mode
- uint16_t _get_udp_port(
- uint8_t destination,
- uint8_t prefix);
-
- uhd::both_xports_t make_transport(
- const uhd::sid_t &address,
- const xport_type_t type,
- const uhd::device_addr_t &args
- );
-
- uhd::endianness_t get_transport_endianness(size_t) {
- return uhd::ENDIANNESS_LITTLE;
- };
-
- /************************************************************************
- * Helpers
- ***********************************************************************/
- void _update_clock_source(const std::string &);
-
-private: // members
- const uhd::device_addr_t _device_addr;
- xport_t _xport_path;
- e300_fifo_interface::sptr _fifo_iface;
- std::atomic<size_t> _sid_framer;
- boost::dynamic_bitset<> _dma_chans_available;
- global_regs::sptr _global_regs;
- e300_sensor_manager::sptr _sensor_manager;
- e300_eeprom_manager::sptr _eeprom_manager;
- uhd::transport::zero_copy_xport_params _data_xport_params;
- uhd::transport::zero_copy_xport_params _ctrl_xport_params;
- std::string _idle_image;
- bool _do_not_reload;
-#ifdef E300_GPSD
- gpsd_iface::sptr _gps;
- static const size_t _GPS_TIMEOUT = 5;
-#endif
-};
-
-}}} // namespace uhd::usrp::e300
-
-#endif /* INCLUDED_E300_IMPL_HPP */
diff --git a/host/lib/usrp/e300/e300_io_impl.cpp b/host/lib/usrp/e300/e300_io_impl.cpp
deleted file mode 100644
index 4460d5616..000000000
--- a/host/lib/usrp/e300/e300_io_impl.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-//
-// Copyright 2013-2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "e300_regs.hpp"
-#include "e300_impl.hpp"
-#include "e300_fpga_defs.hpp"
-#include "e300_defaults.hpp"
-#include "../../transport/super_recv_packet_handler.hpp"
-#include "../../transport/super_send_packet_handler.hpp"
-#include <uhd/utils/tasks.hpp>
-#include <boost/bind.hpp>
-#include <boost/format.hpp>
-
-using namespace uhd;
-using namespace uhd::usrp;
-using namespace uhd::transport;
-
-namespace uhd { namespace usrp { namespace e300 {
-
-uhd::device_addr_t e300_impl::get_rx_hints(size_t)
-{
- return uhd::device_addr_t(str(boost::format("max_recv_window=%d") % DEFAULT_RX_DATA_NUM_FRAMES));
-}
-
-}}} // namespace
diff --git a/host/lib/usrp/e300/e300_network.cpp b/host/lib/usrp/e300/e300_network.cpp
deleted file mode 100644
index d9a104dda..000000000
--- a/host/lib/usrp/e300/e300_network.cpp
+++ /dev/null
@@ -1,655 +0,0 @@
-//
-// Copyright 2013-2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "e300_network.hpp"
-
-#ifdef E300_NATIVE
-
-#include "e300_impl.hpp"
-
-#include "e300_sensor_manager.hpp"
-#include "e300_fifo_config.hpp"
-#include "e300_spi.hpp"
-#include "e300_i2c.hpp"
-#include "e300_defaults.hpp"
-#include "e300_common.hpp"
-#include "e300_remote_codec_ctrl.hpp"
-
-#include <uhd/utils/log.hpp>
-#include <uhd/utils/byteswap.hpp>
-#include <uhd/utils/paths.hpp>
-
-#include <uhdlib/usrp/common/ad9361_ctrl.hpp>
-
-#include <boost/asio.hpp>
-#include <boost/filesystem.hpp>
-#include <boost/make_shared.hpp>
-
-#include <fstream>
-#include <chrono>
-#include <thread>
-
-using namespace uhd;
-using namespace uhd::transport;
-namespace asio = boost::asio;
-namespace fs = boost::filesystem;
-
-namespace uhd { namespace usrp { namespace e300 {
-
-static const size_t E300_NETWORK_DEBUG = false;
-
-static inline bool wait_for_recv_ready(int sock_fd, const size_t timeout_ms)
-{
- //setup timeval for timeout
- timeval tv;
- tv.tv_sec = 0;
- tv.tv_usec = timeout_ms*1000;
-
- //setup rset for timeout
- fd_set rset;
- FD_ZERO(&rset);
- FD_SET(sock_fd, &rset);
-
- //call select with timeout on receive socket
- return ::select(sock_fd+1, &rset, NULL, NULL, &tv) > 0;
-}
-
-static boost::mutex endpoint_mutex;
-
-/***********************************************************************
- * Receive tunnel - forwards recv interface to send socket
- **********************************************************************/
-static void e300_recv_tunnel(
- const std::string &name,
- uhd::transport::zero_copy_if::sptr recver,
- boost::shared_ptr<asio::ip::udp::socket> sender,
- asio::ip::udp::endpoint *endpoint,
- bool *running
-)
-{
- asio::ip::udp::endpoint _tx_endpoint;
- try
- {
- while (*running)
- {
- //step 1 - get the buffer
- managed_recv_buffer::sptr buff = recver->get_recv_buff();
- if (not buff) continue;
- if (E300_NETWORK_DEBUG) UHD_LOGGER_INFO("E300") << name << " got " << buff->size();
-
- //step 1.5 -- update endpoint
- {
- boost::mutex::scoped_lock l(endpoint_mutex);
- _tx_endpoint = *endpoint;
- }
-
- //step 2 - send to the socket
- sender->send_to(asio::buffer(buff->cast<const void *>(), buff->size()), _tx_endpoint);
- }
- }
- catch(const std::exception &ex)
- {
- UHD_LOGGER_ERROR("E300") << "e300_recv_tunnel exit " << name << " " << ex.what();
- }
- catch(...)
- {
- UHD_LOGGER_ERROR("E300") << "e300_recv_tunnel exit " << name ;
- }
- UHD_LOGGER_INFO("E300") << "e300_recv_tunnel exit " << name;
- *running = false;
-}
-
-/***********************************************************************
- * Send tunnel - forwards recv socket to send interface
- **********************************************************************/
-static void e300_send_tunnel(
- const std::string &name,
- boost::shared_ptr<asio::ip::udp::socket> recver,
- uhd::transport::zero_copy_if::sptr sender,
- asio::ip::udp::endpoint *endpoint,
- bool *running
-)
-{
- asio::ip::udp::endpoint _rx_endpoint;
- try
- {
- while (*running)
- {
- //step 1 - get the buffer
- managed_send_buffer::sptr buff = sender->get_send_buff();
- if (not buff) continue;
-
- //step 2 - recv from socket
- while (not wait_for_recv_ready(recver->native_handle(), 100) and *running){}
- if (not *running) break;
- const size_t num_bytes = recver->receive_from(asio::buffer(buff->cast<void *>(), buff->size()), _rx_endpoint);
- if (E300_NETWORK_DEBUG) UHD_LOGGER_INFO("E300") << name << " got " << num_bytes;
-
- //step 2.5 -- update endpoint
- {
- boost::mutex::scoped_lock l(endpoint_mutex);
- *endpoint = _rx_endpoint;
- }
-
- //step 3 - commit the buffer
- buff->commit(num_bytes);
- }
- }
- catch(const std::exception &ex)
- {
- UHD_LOGGER_ERROR("E300") << "e300_send_tunnel exit " << name << " " << ex.what() ;
- }
- catch(...)
- {
- UHD_LOGGER_ERROR("E300") << "e300_send_tunnel exit " << name ;
- }
- UHD_LOGGER_INFO("E300") << "e300_send_tunnel exit " << name;
- *running = false;
-}
-
-static void e300_codec_ctrl_tunnel(
- const std::string &name,
- boost::shared_ptr<asio::ip::udp::socket> socket,
- ad9361_ctrl::sptr _codec_ctrl,
- asio::ip::udp::endpoint *endpoint,
- bool *running
-)
-{
- asio::ip::udp::endpoint _endpoint;
- try
- {
- while (*running)
- {
- uint8_t in_buff[64] = {};
- uint8_t out_buff[64] = {};
-
- const size_t num_bytes = socket->receive_from(asio::buffer(in_buff), *endpoint);
-
- typedef e300_remote_codec_ctrl::transaction_t codec_xact_t;
-
- if (num_bytes < sizeof(codec_xact_t)) {
- std::cout << "Received short packet of " << num_bytes << std::endl;
- continue;
- }
-
- codec_xact_t *in = reinterpret_cast<codec_xact_t*>(in_buff);
- codec_xact_t *out = reinterpret_cast<codec_xact_t*>(out_buff);
- std::memcpy(out, in, sizeof(codec_xact_t));
-
- std::string which_str;
- switch (uhd::ntohx<uint32_t>(in->which)) {
- case codec_xact_t::CHAIN_TX1:
- which_str = "TX1"; break;
- case codec_xact_t::CHAIN_TX2:
- which_str = "TX2"; break;
- case codec_xact_t::CHAIN_RX1:
- which_str = "RX1"; break;
- case codec_xact_t::CHAIN_RX2:
- which_str = "RX2"; break;
- default:
- which_str = ""; break;
- }
-
- switch (uhd::ntohx<uint32_t>(in->action)) {
- case codec_xact_t::ACTION_SET_GAIN:
- out->gain = _codec_ctrl->set_gain(which_str, in->gain);
- break;
- case codec_xact_t::ACTION_SET_CLOCK_RATE:
- out->rate = _codec_ctrl->set_clock_rate(in->rate);
- break;
- case codec_xact_t::ACTION_SET_ACTIVE_CHANS:
- _codec_ctrl->set_active_chains(
- uhd::ntohx<uint32_t>(in->bits) & (1<<0),
- uhd::ntohx<uint32_t>(in->bits) & (1<<1),
- uhd::ntohx<uint32_t>(in->bits) & (1<<2),
- uhd::ntohx<uint32_t>(in->bits) & (1<<3));
- break;
- case codec_xact_t::ACTION_TUNE:
- out->freq = _codec_ctrl->tune(which_str, in->freq);
- break;
- case codec_xact_t::ACTION_GET_FREQ:
- out->freq = _codec_ctrl->get_freq(which_str);
- break;
- case codec_xact_t::ACTION_SET_LOOPBACK:
- _codec_ctrl->data_port_loopback(
- uhd::ntohx<uint32_t>(in->bits) & 1);
- break;
- case codec_xact_t::ACTION_GET_RSSI:
- out->rssi = _codec_ctrl->get_rssi(which_str).to_real();
- break;
- case codec_xact_t::ACTION_GET_TEMPERATURE:
- out->temp = _codec_ctrl->get_temperature().to_real();
- break;
- case codec_xact_t::ACTION_SET_DC_OFFSET_AUTO:
- _codec_ctrl->set_dc_offset_auto(which_str, in->use_dc_correction == 1);
- break;
- case codec_xact_t::ACTION_SET_IQ_BALANCE_AUTO:
- _codec_ctrl->set_iq_balance_auto(which_str, in->use_iq_correction == 1);
- case codec_xact_t::ACTION_SET_AGC:
- _codec_ctrl->set_agc(which_str, in->use_agc == 1);
- break;
- case codec_xact_t::ACTION_SET_AGC_MODE:
- if(in->agc_mode == 0) {
- _codec_ctrl->set_agc_mode(which_str, "slow");
- } else if (in->agc_mode == 1) {
- _codec_ctrl->set_agc_mode(which_str, "fast");
- }
- break;
- case codec_xact_t::ACTION_SET_BW:
- out->bw = _codec_ctrl->set_bw_filter(which_str, in->bw);
- break;
- default:
- UHD_LOGGER_INFO("E300") << "Got unknown request?!";
- //Zero out actions to fail this request on client
- out->action = uhd::htonx<uint32_t>(0);
- }
-
- socket->send_to(asio::buffer(out_buff, 64), *endpoint);
- }
- }
- catch(const std::exception &ex)
- {
- UHD_LOGGER_ERROR("E300") << "e300_ctrl_tunnel exit " << name << " " << ex.what() ;
- }
- catch(...)
- {
- UHD_LOGGER_ERROR("E300") << "e300_ctrl_tunnel exit " << name ;
- }
- UHD_LOGGER_INFO("E300") << "e300_ctrl_tunnel exit " << name;
- *running = false;
-}
-
-static void e300_global_regs_tunnel(
- const std::string &name,
- boost::shared_ptr<asio::ip::udp::socket> socket,
- global_regs::sptr regs,
- asio::ip::udp::endpoint *endpoint,
- bool *running
-)
-{
- UHD_ASSERT_THROW(regs);
- asio::ip::udp::endpoint _endpoint;
- try
- {
- while (*running)
- {
- uint8_t in_buff[16] = {};
-
- const size_t num_bytes = socket->receive_from(asio::buffer(in_buff), *endpoint);
-
- if (num_bytes < 16) {
- std::cout << "Received short packet: " << num_bytes << std::endl;
- continue;
- }
-
- global_regs_transaction_t *in =
- reinterpret_cast<global_regs_transaction_t *>(in_buff);
-
- if(uhd::ntohx<uint32_t>(in->is_poke)) {
- regs->poke32(uhd::ntohx<uint32_t>(in->addr), uhd::ntohx<uint32_t>(in->data));
- }
- else {
- in->data = uhd::htonx<uint32_t>(regs->peek32(uhd::ntohx<uint32_t>(in->addr)));
- socket->send_to(asio::buffer(in_buff, 16), *endpoint);
- }
- }
- }
- catch(const std::exception &ex)
- {
- UHD_LOGGER_ERROR("E300") << "e300_gregs_tunnel exit " << name << " " << ex.what() ;
- }
- catch(...)
- {
- UHD_LOGGER_ERROR("E300") << "e300_gregs_tunnel exit " << name ;
- }
- UHD_LOGGER_INFO("E300") << "e300_gregs_tunnel exit " << name;
- *running = false;
-}
-
-static void e300_sensor_tunnel(
- const std::string &name,
- boost::shared_ptr<asio::ip::udp::socket> socket,
- e300_sensor_manager::sptr sensor_manager,
- asio::ip::udp::endpoint *endpoint,
- bool *running
-)
-{
- asio::ip::udp::endpoint _endpoint;
- try
- {
- while (*running)
- {
- uint8_t in_buff[128] = {};
-
- const size_t num_bytes = socket->receive_from(asio::buffer(in_buff), *endpoint);
-
- if (num_bytes < sizeof(sensor_transaction_t)) {
- std::cout << "Received short packet: " << num_bytes << std::endl;
- continue;
- }
-
- uhd::usrp::e300::sensor_transaction_t *in =
- reinterpret_cast<uhd::usrp::e300::sensor_transaction_t *>(in_buff);
-
- if (uhd::ntohx(in->which) == ZYNQ_TEMP) {
- sensor_value_t temp = sensor_manager->get_mb_temp();
- // TODO: This is ugly ... use proper serialization
- in->value = uhd::htonx<uint32_t>(
- e300_sensor_manager::pack_float_in_uint32_t(temp.to_real()));
- } else if (uhd::ntohx(in->which) == REF_LOCK) {
- in->value = uhd::htonx<uint32_t>(
- sensor_manager->get_ref_lock().to_bool() ? 1 : 0);
- } else
- UHD_LOGGER_INFO("E300") << "Got unknown request?!";
-
- socket->send_to(asio::buffer(in_buff, sizeof(sensor_transaction_t)), *endpoint);
- }
- }
- catch(const std::exception &ex)
- {
- UHD_LOGGER_ERROR("E300") << "e300_sensor_tunnel exit " << name << " " << ex.what() ;
- }
- catch(...)
- {
- UHD_LOGGER_ERROR("E300") << "e300_sensor_tunnel exit " << name ;
- }
- UHD_LOGGER_INFO("E300") << "e300_sensor_tunnel exit " << name;
- *running = false;
-}
-
-static void e300_i2c_tunnel(
- const std::string &name,
- boost::shared_ptr<asio::ip::udp::socket> socket,
- uhd::usrp::e300::i2c::sptr i2c,
- asio::ip::udp::endpoint *endpoint,
- bool *running
-)
-{
- UHD_ASSERT_THROW(i2c);
- asio::ip::udp::endpoint _endpoint;
- try
- {
- while (*running)
- {
- uint8_t in_buff[sizeof(uhd::usrp::e300::i2c_transaction_t)];
-
- const size_t num_bytes = socket->receive_from(asio::buffer(in_buff), *endpoint);
-
- if (num_bytes < sizeof(uhd::usrp::e300::i2c_transaction_t)) {
- std::cout << "Received short packet: " << num_bytes << std::endl;
- continue;
- }
-
- uhd::usrp::e300::i2c_transaction_t *in =
- reinterpret_cast<uhd::usrp::e300::i2c_transaction_t *>(in_buff);
-
- // byte addressed accesses go through here
- if(in->type & i2c::ONEBYTE) {
- if(in->type & i2c::WRITE) {
- i2c->set_i2c_reg8(
- in->addr,
- uhd::ntohx<uint16_t>(in->reg), in->data);
- } else {
- in->data = i2c->get_i2c_reg8(in->addr, uhd::ntohx<uint16_t>(in->reg));
- socket->send_to(asio::buffer(in_buff, sizeof(in_buff)), *endpoint);
- }
-
- // 2 byte addressed accesses go through here
- } else if (in->type & i2c::TWOBYTE) {
- if(in->type & i2c::WRITE) {
- i2c->set_i2c_reg16(
- in->addr,
- uhd::ntohx<uint16_t>(in->reg), in->data);
- } else {
- in->data = i2c->get_i2c_reg16(in->addr, uhd::ntohx<uint16_t>(in->reg));
- socket->send_to(asio::buffer(in_buff, sizeof(in_buff)), *endpoint);
- }
-
- } else {
- UHD_LOGGER_ERROR("E300") << "e300_i2c_tunnel could not handle message." ;
- }
- }
- }
- catch(const std::exception &ex)
- {
- UHD_LOGGER_ERROR("E300") << "e300_i2c_tunnel exit " << name << " " << ex.what() ;
- }
- catch(...)
- {
- UHD_LOGGER_ERROR("E300") << "e300_i2c_tunnel exit " << name ;
- }
- UHD_LOGGER_INFO("E300") << "e300_i2c_tunnel exit " << name;
- *running = false;
-}
-
-
-
-
-class network_server_impl : public network_server
-{
-public:
- network_server_impl(const uhd::device_addr_t &device_addr);
- virtual ~network_server_impl(void);
- void run(void);
-
-private:
- struct xports_t
- {
- uhd::transport::zero_copy_if::sptr send_ctrl_xport;
- uhd::transport::zero_copy_if::sptr recv_ctrl_xport;
- uhd::transport::zero_copy_if::sptr tx_data_xport;
- uhd::transport::zero_copy_if::sptr tx_flow_xport;
- uhd::transport::zero_copy_if::sptr rx_data_xport;
- uhd::transport::zero_copy_if::sptr rx_flow_xport;
- };
-
-private:
- void _run_server(
- const std::string &port,
- const std::string &what,
- const size_t fe);
-
-private:
- boost::shared_ptr<e300_fifo_interface> _fifo_iface;
- xports_t _xports[2];
- boost::shared_ptr<ad9361_ctrl> _codec_ctrl;
- boost::shared_ptr<global_regs> _global_regs;
- boost::shared_ptr<e300_sensor_manager> _sensor_manager;
- boost::shared_ptr<e300_eeprom_manager> _eeprom_manager;
-};
-
-network_server_impl::~network_server_impl(void)
-{
-}
-
-/***********************************************************************
- * The UDP server itself
- **********************************************************************/
-void network_server_impl::_run_server(
- const std::string &port,
- const std::string &what,
- const size_t fe)
-{
- asio::io_service io_service;
- asio::ip::udp::resolver resolver(io_service);
- asio::ip::udp::resolver::query query(asio::ip::udp::v4(), "0.0.0.0", port);
- asio::ip::udp::endpoint endpoint = *resolver.resolve(query);
-
- //boost::shared_ptr<asio::ip::udp::acceptor> acceptor(new asio::ip::udp::acceptor(io_service, endpoint));
- while (not boost::this_thread::interruption_requested())
- {
- UHD_LOGGER_INFO("E300") << "e300 run server on port " << port << " for " << what;
- try
- {
- //while (not wait_for_recv_ready(acceptor->native(), 100))
- //{
- // if (boost::this_thread::interruption_requested()) return;
- //}
- boost::shared_ptr<asio::ip::udp::socket> socket;
- socket.reset(new asio::ip::udp::socket(io_service, endpoint));
- //acceptor->accept(*socket);
- UHD_LOGGER_INFO("E300") << "e300 socket accept on port " << port << " for " << what;
- //asio::ip::udp::no_delay option(true);
- //socket->set_option(option);
- boost::thread_group tg;
- bool running = true;
- xports_t &perif = _xports[fe];
- if (what == "RX") {
- tg.create_thread(boost::bind(&e300_recv_tunnel, "RX data tunnel", perif.rx_data_xport, socket, &endpoint, &running));
- tg.create_thread(boost::bind(&e300_send_tunnel, "RX flow tunnel", socket, perif.rx_flow_xport, &endpoint, &running));
- }
- if (what == "TX") {
- tg.create_thread(boost::bind(&e300_recv_tunnel, "TX flow tunnel", perif.tx_flow_xport, socket, &endpoint, &running));
- tg.create_thread(boost::bind(&e300_send_tunnel, "TX data tunnel", socket, perif.tx_data_xport, &endpoint, &running));
- }
- if (what == "CTRL") {
- tg.create_thread(boost::bind(&e300_recv_tunnel, "response tunnel", perif.recv_ctrl_xport, socket, &endpoint, &running));
- tg.create_thread(boost::bind(&e300_send_tunnel, "control tunnel", socket, perif.send_ctrl_xport, &endpoint, &running));
- }
- if (what == "CODEC") {
- tg.create_thread(boost::bind(&e300_codec_ctrl_tunnel, "CODEC tunnel", socket, _codec_ctrl, &endpoint, &running));
- }
- if (what == "I2C") {
- tg.create_thread(boost::bind(&e300_i2c_tunnel, "I2C tunnel", socket, _eeprom_manager->get_i2c_sptr(), &endpoint, &running));
- }
- if (what == "GREGS") {
- tg.create_thread(boost::bind(&e300_global_regs_tunnel, "GREGS tunnel", socket, _global_regs, &endpoint, &running));
- }
- if (what == "SENSOR") {
- tg.create_thread(boost::bind(&e300_sensor_tunnel, "SENSOR tunnel", socket, _sensor_manager, &endpoint, &running));
- }
-
- tg.join_all();
- socket->close();
- socket.reset();
- }
- catch(...){}
- }
-}
-
-void network_server_impl::run()
-{
- for(;;)
- {
- boost::thread_group tg;
- tg.create_thread(boost::bind(&network_server_impl::_run_server, this, E300_SERVER_RX_PORT0, "RX",0));
- tg.create_thread(boost::bind(&network_server_impl::_run_server, this, E300_SERVER_TX_PORT0, "TX",0));
- tg.create_thread(boost::bind(&network_server_impl::_run_server, this, E300_SERVER_CTRL_PORT0, "CTRL",0));
-
- tg.create_thread(boost::bind(&network_server_impl::_run_server, this, E300_SERVER_RX_PORT1, "RX",1));
- tg.create_thread(boost::bind(&network_server_impl::_run_server, this, E300_SERVER_TX_PORT1, "TX",1));
- tg.create_thread(boost::bind(&network_server_impl::_run_server, this, E300_SERVER_CTRL_PORT1, "CTRL",1));
-
- tg.create_thread(boost::bind(&network_server_impl::_run_server, this, E300_SERVER_SENSOR_PORT, "SENSOR", 0 /*don't care */));
-
- tg.create_thread(boost::bind(&network_server_impl::_run_server, this, E300_SERVER_CODEC_PORT, "CODEC", 0 /*don't care */));
- tg.create_thread(boost::bind(&network_server_impl::_run_server, this, E300_SERVER_GREGS_PORT, "GREGS", 0 /*don't care */));
- tg.create_thread(boost::bind(&network_server_impl::_run_server, this, E300_SERVER_I2C_PORT, "I2C", 0 /*don't care */));
- tg.join_all();
- }
-}
-network_server_impl::network_server_impl(const uhd::device_addr_t &device_addr)
-{
- _eeprom_manager = boost::make_shared<e300_eeprom_manager>(i2c::make_i2cdev(E300_I2CDEV_DEVICE));
- if (not device_addr.has_key("no_reload_fpga")) {
- // Load FPGA image if provided via args
- if (device_addr.has_key("fpga")) {
- common::load_fpga_image(device_addr["fpga"]);
- // Else load the FPGA image based on the product ID
- } else {
- //extract the FPGA path for the e300
- const uint16_t pid = boost::lexical_cast<uint16_t>(
- _eeprom_manager->get_mb_eeprom()["product"]);
- std::string fpga_image;
- switch(e300_eeprom_manager::get_mb_type(pid)) {
- case e300_eeprom_manager::USRP_E310_SG1_MB:
- fpga_image = find_image_path(E310_SG1_FPGA_FILE_NAME);
- break;
- case e300_eeprom_manager::USRP_E310_SG3_MB:
- fpga_image = find_image_path(E310_SG3_FPGA_FILE_NAME);
- break;
- case e300_eeprom_manager::USRP_E300_MB:
- fpga_image = find_image_path(E300_FPGA_FILE_NAME);
- break;
- case e300_eeprom_manager::UNKNOWN:
- default:
- UHD_LOGGER_WARNING("E300") << "Unknown motherboard type, loading e300 image."
- ;
- fpga_image = find_image_path(E300_FPGA_FILE_NAME);
- break;
- }
- common::load_fpga_image(fpga_image);
- }
- }
-
- uhd::transport::zero_copy_xport_params ctrl_xport_params;
- ctrl_xport_params.recv_frame_size = e300::DEFAULT_CTRL_FRAME_SIZE;
- ctrl_xport_params.num_recv_frames = e300::DEFAULT_CTRL_NUM_FRAMES;
- ctrl_xport_params.send_frame_size = e300::DEFAULT_CTRL_FRAME_SIZE;
- ctrl_xport_params.num_send_frames = e300::DEFAULT_CTRL_NUM_FRAMES;
-
- uhd::transport::zero_copy_xport_params data_xport_params;
- data_xport_params.recv_frame_size = device_addr.cast<size_t>("recv_frame_size", e300::DEFAULT_RX_DATA_FRAME_SIZE);
- data_xport_params.num_recv_frames = device_addr.cast<size_t>("num_recv_frames", e300::DEFAULT_RX_DATA_NUM_FRAMES);
- data_xport_params.send_frame_size = device_addr.cast<size_t>("send_frame_size", e300::DEFAULT_TX_DATA_FRAME_SIZE);
- data_xport_params.num_send_frames = device_addr.cast<size_t>("num_send_frames", e300::DEFAULT_TX_DATA_NUM_FRAMES);
- // until we figure out why this goes wrong we'll keep this hack around
- data_xport_params.recv_frame_size =
- std::min(e300::MAX_NET_RX_DATA_FRAME_SIZE, data_xport_params.recv_frame_size);
- data_xport_params.send_frame_size =
- std::min(e300::MAX_NET_TX_DATA_FRAME_SIZE, data_xport_params.send_frame_size);
-
-
- e300_fifo_config_t fifo_cfg;
- try {
- fifo_cfg = e300_read_sysfs();
- } catch (uhd::lookup_error &e) {
- throw uhd::runtime_error("Failed to get driver parameters from sysfs.");
- }
- _fifo_iface = e300_fifo_interface::make(fifo_cfg);
- _global_regs = global_regs::make(_fifo_iface->get_global_regs_base());
-
- // static mapping, boooohhhhhh
- _xports[0].send_ctrl_xport = _fifo_iface->make_send_xport(E300_R0_CTRL_STREAM, ctrl_xport_params);
- _xports[0].recv_ctrl_xport = _fifo_iface->make_recv_xport(E300_R0_CTRL_STREAM, ctrl_xport_params);
- _xports[0].tx_data_xport = _fifo_iface->make_send_xport(E300_R0_TX_DATA_STREAM, data_xport_params);
- _xports[0].tx_flow_xport = _fifo_iface->make_recv_xport(E300_R0_TX_DATA_STREAM, ctrl_xport_params);
- _xports[0].rx_data_xport = _fifo_iface->make_recv_xport(E300_R0_RX_DATA_STREAM, data_xport_params);
- _xports[0].rx_flow_xport = _fifo_iface->make_send_xport(E300_R0_RX_DATA_STREAM, ctrl_xport_params);
-
- _xports[1].send_ctrl_xport = _fifo_iface->make_send_xport(E300_R1_CTRL_STREAM, ctrl_xport_params);
- _xports[1].recv_ctrl_xport = _fifo_iface->make_recv_xport(E300_R1_CTRL_STREAM, ctrl_xport_params);
- _xports[1].tx_data_xport = _fifo_iface->make_send_xport(E300_R1_TX_DATA_STREAM, data_xport_params);
- _xports[1].tx_flow_xport = _fifo_iface->make_recv_xport(E300_R1_TX_DATA_STREAM, ctrl_xport_params);
- _xports[1].rx_data_xport = _fifo_iface->make_recv_xport(E300_R1_RX_DATA_STREAM, data_xport_params);
- _xports[1].rx_flow_xport = _fifo_iface->make_send_xport(E300_R1_RX_DATA_STREAM, ctrl_xport_params);
-
- ad9361_params::sptr client_settings = boost::make_shared<e300_ad9361_client_t>();
- _codec_ctrl = ad9361_ctrl::make_spi(client_settings, spi::make(E300_SPIDEV_DEVICE), 1);
- // This is horrible ... why do I have to sleep here?
- std::this_thread::sleep_for(std::chrono::milliseconds(100));
- _sensor_manager = e300_sensor_manager::make_local(_global_regs);
-}
-
-}}} // namespace
-
-using namespace uhd::usrp::e300;
-
-network_server::sptr network_server::make(const uhd::device_addr_t &device_addr)
-{
- return sptr(new network_server_impl(device_addr));
-}
-
-#else
-
-using namespace uhd::usrp::e300;
-
-network_server::sptr network_server::make(const uhd::device_addr_t &)
-{
- throw uhd::assertion_error("network_server::make() !E300_NATIVE");
-}
-#endif
diff --git a/host/lib/usrp/e300/e300_network.hpp b/host/lib/usrp/e300/e300_network.hpp
deleted file mode 100644
index caa25b0ad..000000000
--- a/host/lib/usrp/e300/e300_network.hpp
+++ /dev/null
@@ -1,33 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_E300_NETWORK_HPP
-#define INCLUDED_E300_NETWORK_HPP
-
-#include <string>
-#include <uhd/utils/noncopyable.hpp>
-
-#include <uhd/device.hpp>
-
-
-static const std::string E310_FPGA_FILE_NAME = "usrp_e310_fpga.bit";
-static const std::string E300_FPGA_FILE_NAME = "usrp_e300_fpga.bit";
-
-namespace uhd { namespace usrp { namespace e300 {
-
-class UHD_API network_server : uhd::noncopyable
-{
-public:
- typedef boost::shared_ptr<network_server> sptr;
- virtual void run(void) = 0;
-
- static sptr make(const uhd::device_addr_t &device_addr);
-};
-
-
-}}}
-#endif // INCLUDED_E300_NETWORK_HPP
diff --git a/host/lib/usrp/e300/e300_regs.hpp b/host/lib/usrp/e300/e300_regs.hpp
deleted file mode 100644
index 88d58907b..000000000
--- a/host/lib/usrp/e300/e300_regs.hpp
+++ /dev/null
@@ -1,25 +0,0 @@
-//
-// Copyright 2012-2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_E300_REGS_HPP
-#define INCLUDED_E300_REGS_HPP
-
-#include <stdint.h>
-#include <uhd/config.hpp>
-
-static const uint32_t VCRX_V2 = 15;
-static const uint32_t VCRX_V1 = 14;
-static const uint32_t VCTXRX_V2 = 13;
-static const uint32_t VCTXRX_V1 = 12;
-static const uint32_t TX_ENABLEB = 11;
-static const uint32_t TX_ENABLEA = 10;
-static const uint32_t RXC_BANDSEL = 8;
-static const uint32_t RXB_BANDSEL = 6;
-static const uint32_t RX_BANDSEL = 3;
-static const uint32_t TX_BANDSEL = 0;
-
-#endif /* INCLUDED_E300_REGS_HPP */
diff --git a/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp b/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp
deleted file mode 100644
index 5692a138e..000000000
--- a/host/lib/usrp/e300/e300_remote_codec_ctrl.cpp
+++ /dev/null
@@ -1,285 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "e300_remote_codec_ctrl.hpp"
-
-#include <stdint.h>
-#include <uhd/exception.hpp>
-#include <uhd/utils/byteswap.hpp>
-#include <cstring>
-#include <iostream>
-
-namespace uhd { namespace usrp { namespace e300 {
-
-class e300_remote_codec_ctrl_impl : public e300_remote_codec_ctrl
-{
-public:
- e300_remote_codec_ctrl_impl(uhd::transport::zero_copy_if::sptr xport) : _xport(xport)
- {
- }
-
- virtual ~e300_remote_codec_ctrl_impl(void)
- {
- }
-
-
- double set_gain(const std::string &which, const double value)
- {
- _clear();
- _args.action = uhd::htonx<uint32_t>(transaction_t::ACTION_SET_GAIN);
- if (which == "TX1") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_TX1);
- else if (which == "TX2") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_TX2);
- else if (which == "RX1") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_RX1);
- else if (which == "RX2") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_RX2);
- else throw std::runtime_error("e300_remote_codec_ctrl_impl incorrect chain string.");
- _args.gain = value;
-
- _transact();
- return _retval.gain;
- }
-
- double set_clock_rate(const double rate)
- {
- _clear();
- _args.action = uhd::htonx<uint32_t>(
- transaction_t::ACTION_SET_CLOCK_RATE);
- _args.which = uhd::htonx<uint32_t>(
- transaction_t::CHAIN_NONE); /*Unused*/
- _args.rate = rate;
-
- _transact();
- return _retval.gain;
- }
-
- void set_active_chains(bool tx1, bool tx2, bool rx1, bool rx2)
- {
- _clear();
- _args.action = uhd::htonx<uint32_t>(
- transaction_t::ACTION_SET_ACTIVE_CHANS);
- /*Unused*/
- _args.which = uhd::htonx<uint32_t>(
- transaction_t::CHAIN_NONE);
- _args.bits = uhd::htonx<uint32_t>(
- (tx1 ? (1<<0) : 0) |
- (tx2 ? (1<<1) : 0) |
- (rx1 ? (1<<2) : 0) |
- (rx2 ? (1<<3) : 0));
-
- _transact();
- }
-
- double tune(const std::string &which, const double value)
- {
- _clear();
- _args.action = uhd::htonx<uint32_t>(transaction_t::ACTION_TUNE);
- if (which == "TX1") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_TX1);
- else if (which == "TX2") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_TX2);
- else if (which == "RX1") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_RX1);
- else if (which == "RX2") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_RX2);
- else throw std::runtime_error("e300_remote_codec_ctrl_impl incorrect chain string.");
- _args.freq = value;
-
- _transact();
- return _retval.freq;
- }
-
- double get_freq(const std::string &which)
- {
- _clear();
- _args.action = uhd::htonx<uint32_t>(transaction_t::ACTION_GET_FREQ);
- if (which == "TX1") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_TX1);
- else if (which == "TX2") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_TX2);
- else if (which == "RX1") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_RX1);
- else if (which == "RX2") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_RX2);
- else throw std::runtime_error("e300_remote_codec_ctrl_impl incorrect chain string.");
-
- _transact();
- return _retval.freq;
- }
-
- void data_port_loopback(const bool on)
- {
- _clear();
- _args.action = uhd::htonx<uint32_t>(transaction_t::ACTION_SET_LOOPBACK);
- _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_NONE); /*Unused*/
- _args.bits = uhd::htonx<uint32_t>(on ? 1 : 0);
-
- _transact();
- }
-
- sensor_value_t get_rssi(const std::string &which)
- {
- _clear();
- _args.action = uhd::htonx<uint32_t>(transaction_t::ACTION_GET_RSSI);
- if (which == "RX1") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_RX1);
- else if (which == "RX2") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_RX2);
- else throw std::runtime_error("e300_remote_codec_ctrl_impl incorrect chain string.");
- _args.bits = uhd::htonx<uint32_t>(0);
-
- _transact();
- return sensor_value_t("RSSI", _retval.rssi, "dB");
- }
-
- sensor_value_t get_temperature()
- {
- _clear();
- _args.action = uhd::htonx<uint32_t>(transaction_t::ACTION_GET_TEMPERATURE);
- _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_NONE); /*Unused*/
- _args.bits = uhd::htonx<uint32_t>(0);
-
- _transact();
- return sensor_value_t("temp", _retval.temp, "C");
- }
-
- void set_dc_offset_auto(const std::string &which, const bool on)
- {
- _clear();
- _args.action = uhd::htonx<uint32_t>(transaction_t::ACTION_SET_DC_OFFSET_AUTO);
- if (which == "TX1") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_TX1);
- else if (which == "TX2") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_TX2);
- else if (which == "RX1") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_RX1);
- else if (which == "RX2") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_RX2);
- else throw std::runtime_error("e300_remote_codec_ctrl_impl incorrect chain string.");
- _args.use_dc_correction = on ? 1 : 0;
-
- _transact();
- }
-
- void set_iq_balance_auto(const std::string &which, const bool on)
- {
- _clear();
- _args.action = uhd::htonx<uint32_t>(transaction_t::ACTION_SET_IQ_BALANCE_AUTO);
- if (which == "TX1") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_TX1);
- else if (which == "TX2") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_TX2);
- else if (which == "RX1") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_RX1);
- else if (which == "RX2") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_RX2);
- else throw std::runtime_error("e300_remote_codec_ctrl_impl incorrect chain string.");
- _args.use_iq_correction = on ? 1 : 0;
-
- _transact();
- }
-
- void set_agc(const std::string &which, bool enable)
- {
- _clear();
- _args.action = uhd::htonx<uint32_t>(transaction_t::ACTION_SET_AGC);
- if (which == "TX1") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_TX1);
- else if (which == "TX2") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_TX2);
- else if (which == "RX1") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_RX1);
- else if (which == "RX2") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_RX2);
- else throw std::runtime_error("e300_remote_codec_ctrl_impl incorrect chain string.");
- _args.use_agc = enable ? 1 : 0;
-
- _transact();
- }
-
- void set_agc_mode(const std::string &which, const std::string &mode)
- {
- _clear();
- _args.action = uhd::htonx<uint32_t>(transaction_t::ACTION_SET_AGC_MODE);
-
- if (which == "TX1") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_TX1);
- else if (which == "TX2") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_TX2);
- else if (which == "RX1") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_RX1);
- else if (which == "RX2") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_RX2);
- else throw std::runtime_error("e300_remote_codec_ctrl_impl incorrect chain string.");
-
- if(mode == "slow") {
- _args.agc_mode = 0;
- } else if (mode == "fast") {
- _args.agc_mode = 1;
- } else {
- throw std::runtime_error("e300_remote_codec_ctrl_impl incorrect agc mode.");
- }
-
- _transact();
- }
-
- //! set the filter bandwidth for the frontend's analog low pass
- double set_bw_filter(const std::string &which, const double bw)
- {
- _clear();
- _args.action = uhd::htonx<uint32_t>(transaction_t::ACTION_SET_BW);
- if (which == "TX1") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_TX1);
- else if (which == "TX2") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_TX2);
- else if (which == "RX1") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_RX1);
- else if (which == "RX2") _args.which = uhd::htonx<uint32_t>(transaction_t::CHAIN_RX2);
- else throw std::runtime_error("e300_remote_codec_ctrl_impl incorrect chain string.");
- _args.bw = bw;
-
- _transact();
- return _retval.bw;
- }
-
- //! List all available filters by name
- std::vector<std::string> get_filter_names(const std::string &)
- {
- return std::vector<std::string>();
- }
-
- //! Return a list of all filters
- filter_info_base::sptr get_filter(const std::string &, const std::string &)
- {
- UHD_THROW_INVALID_CODE_PATH();
- }
-
- //! Write back a filter
- void set_filter(const std::string &, const std::string &, const filter_info_base::sptr)
- {
- UHD_LOGGER_WARNING("E300") << "Attempting to set filter on E300 in network mode." ;
- }
-
- void output_digital_test_tone(UHD_UNUSED(bool enb))
- {
- UHD_THROW_INVALID_CODE_PATH();
- }
-
- void set_timing_mode(UHD_UNUSED(const std::string &timing_mode))
- {
- UHD_THROW_INVALID_CODE_PATH();
- }
-
-private:
- void _transact() {
- {
- uhd::transport::managed_send_buffer::sptr buff = _xport->get_send_buff(10.0);
- if (not buff or buff->size() < sizeof(_args))
- throw std::runtime_error("e300_remote_codec_ctrl_impl send timeout");
- std::memcpy(buff->cast<void *>(), &_args, sizeof(_args));
- buff->commit(sizeof(_args));
- }
- {
- uhd::transport::managed_recv_buffer::sptr buff = _xport->get_recv_buff(10.0);
- if (not buff or buff->size() < sizeof(_retval))
- throw std::runtime_error("e300_remote_codec_ctrl_impl recv timeout");
- std::memcpy(&_retval, buff->cast<const void *>(), sizeof(_retval));
- }
-
- if (_args.action != _retval.action)
- throw std::runtime_error("e300_remote_codec_ctrl_impl transaction failed.");
- }
-
- void _clear() {
- _args.action = 0;
- _args.which = 0;
- _args.bits = 0;
- _retval.action = 0;
- _retval.which = 0;
- _retval.bits = 0;
- }
-
- uhd::transport::zero_copy_if::sptr _xport;
- transaction_t _args;
- transaction_t _retval;
-};
-
-ad9361_ctrl::sptr e300_remote_codec_ctrl::make(uhd::transport::zero_copy_if::sptr xport)
-{
- return sptr(new e300_remote_codec_ctrl_impl(xport));
-}
-
-}}};
diff --git a/host/lib/usrp/e300/e300_remote_codec_ctrl.hpp b/host/lib/usrp/e300/e300_remote_codec_ctrl.hpp
deleted file mode 100644
index 9c9e16672..000000000
--- a/host/lib/usrp/e300/e300_remote_codec_ctrl.hpp
+++ /dev/null
@@ -1,64 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_E300_REMOTE_CODEC_CTRL_HPP
-#define INCLUDED_E300_REMOTE_CODEC_CTRL_HPP
-
-#include <uhd/transport/zero_copy.hpp>
-#include <uhdlib/usrp/common/ad9361_ctrl.hpp>
-
-namespace uhd { namespace usrp { namespace e300 {
-
-class e300_remote_codec_ctrl : public uhd::usrp::ad9361_ctrl
-{
-public:
- struct transaction_t {
- uint32_t action;
- uint32_t which;
- union {
- double rate;
- double gain;
- double freq;
- double rssi;
- double temp;
- double bw;
- uint32_t use_dc_correction;
- uint32_t use_iq_correction;
- uint32_t use_agc;
- uint32_t agc_mode;
- uint64_t bits;
- };
-
- //Actions
- static const uint32_t ACTION_SET_GAIN = 10;
- static const uint32_t ACTION_SET_CLOCK_RATE = 11;
- static const uint32_t ACTION_SET_ACTIVE_CHANS = 12;
- static const uint32_t ACTION_TUNE = 13;
- static const uint32_t ACTION_SET_LOOPBACK = 14;
- static const uint32_t ACTION_GET_RSSI = 15;
- static const uint32_t ACTION_GET_TEMPERATURE = 16;
- static const uint32_t ACTION_SET_DC_OFFSET_AUTO = 17;
- static const uint32_t ACTION_SET_IQ_BALANCE_AUTO = 18;
- static const uint32_t ACTION_SET_AGC = 19;
- static const uint32_t ACTION_SET_AGC_MODE = 20;
- static const uint32_t ACTION_SET_BW = 21;
- static const uint32_t ACTION_GET_FREQ = 22;
-
- //Values for "which"
- static const uint32_t CHAIN_NONE = 0;
- static const uint32_t CHAIN_TX1 = 1;
- static const uint32_t CHAIN_TX2 = 2;
- static const uint32_t CHAIN_RX1 = 3;
- static const uint32_t CHAIN_RX2 = 4;
- };
-
- static sptr make(uhd::transport::zero_copy_if::sptr xport);
-};
-
-}}};
-
-#endif /* INCLUDED_E300_REMOTE_CODEC_CTRL_HPP */
diff --git a/host/lib/usrp/e300/e300_sensor_manager.cpp b/host/lib/usrp/e300/e300_sensor_manager.cpp
deleted file mode 100644
index fda1f3f80..000000000
--- a/host/lib/usrp/e300/e300_sensor_manager.cpp
+++ /dev/null
@@ -1,207 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include "e300_sensor_manager.hpp"
-
-#include <boost/thread.hpp>
-#include <boost/assign/list_of.hpp>
-#include <boost/format.hpp>
-
-#include <cstring>
-#include <uhd/exception.hpp>
-#include <uhd/utils/byteswap.hpp>
-
-namespace uhd { namespace usrp { namespace e300 {
-
-class e300_sensor_proxy : public e300_sensor_manager
-{
-public:
- e300_sensor_proxy(
- uhd::transport::zero_copy_if::sptr xport) : _xport(xport)
- {
- }
-
- std::vector<std::string> get_sensors()
- {
- return boost::assign::list_of("temp")("ref_locked");
- }
-
- uhd::sensor_value_t get_sensor(const std::string &key)
- {
- if (key == "temp")
- return get_mb_temp();
- else if (key == "ref_locked")
- return get_ref_lock();
- else
- throw uhd::lookup_error(
- str(boost::format("Invalid sensor %s requested.") % key));
- }
-
- uhd::sensor_value_t get_mb_temp(void)
- {
- boost::mutex::scoped_lock(_mutex);
- sensor_transaction_t transaction;
- transaction.which = uhd::htonx<uint32_t>(ZYNQ_TEMP);
- {
- uhd::transport::managed_send_buffer::sptr buff
- = _xport->get_send_buff(1.0);
- if (not buff or buff->size() < sizeof(transaction)) {
- throw uhd::runtime_error("sensor proxy send timeout");
- }
- std::memcpy(
- buff->cast<void *>(),
- &transaction,
- sizeof(transaction));
- buff->commit(sizeof(transaction));
- }
- {
- uhd::transport::managed_recv_buffer::sptr buff
- = _xport->get_recv_buff(1.0);
-
- if (not buff or buff->size() < sizeof(transaction))
- throw uhd::runtime_error("sensor proxy recv timeout");
-
- std::memcpy(
- &transaction,
- buff->cast<const void *>(),
- sizeof(transaction));
- }
- UHD_ASSERT_THROW(uhd::ntohx<uint32_t>(transaction.which) == ZYNQ_TEMP);
- // TODO: Use proper serialization here ...
- return sensor_value_t(
- "temp",
- e300_sensor_manager::unpack_float_from_uint32_t(
- uhd::ntohx(transaction.value)),
- "C");
- }
-
- uhd::sensor_value_t get_ref_lock(void)
- {
- boost::mutex::scoped_lock(_mutex);
- sensor_transaction_t transaction;
- transaction.which = uhd::htonx<uint32_t>(REF_LOCK);
- {
- uhd::transport::managed_send_buffer::sptr buff
- = _xport->get_send_buff(1.0);
- if (not buff or buff->size() < sizeof(transaction)) {
- throw uhd::runtime_error("sensor proxy send timeout");
- }
- std::memcpy(
- buff->cast<void *>(),
- &transaction,
- sizeof(transaction));
- buff->commit(sizeof(transaction));
- }
- {
- uhd::transport::managed_recv_buffer::sptr buff
- = _xport->get_recv_buff(1.0);
-
- if (not buff or buff->size() < sizeof(transaction))
- throw uhd::runtime_error("sensor proxy recv timeout");
-
- std::memcpy(
- &transaction,
- buff->cast<const void *>(),
- sizeof(transaction));
- }
- UHD_ASSERT_THROW(uhd::ntohx<uint32_t>(transaction.which) == REF_LOCK);
- // TODO: Use proper serialization here ...
- return sensor_value_t("Ref", (uhd::ntohx(transaction.value) > 0), "locked", "unlocked");
- }
-
-private:
- uhd::transport::zero_copy_if::sptr _xport;
- boost::mutex _mutex;
-};
-
-}}} // namespace
-
-using namespace uhd::usrp::e300;
-
-e300_sensor_manager::sptr e300_sensor_manager::make_proxy(
- uhd::transport::zero_copy_if::sptr xport)
-{
- return sptr(new e300_sensor_proxy(xport));
-}
-
-#ifdef E300_NATIVE
-#include "e300_fifo_config.hpp"
-
-namespace uhd { namespace usrp { namespace e300 {
-
-static const std::string E300_TEMP_SYSFS = "iio:device0";
-
-class e300_sensor_local : public e300_sensor_manager
-{
-public:
- e300_sensor_local(global_regs::sptr global_regs) :
- _global_regs(global_regs)
- {
- }
-
- std::vector<std::string> get_sensors()
- {
- return boost::assign::list_of("temp")("ref_locked");
- }
-
- uhd::sensor_value_t get_sensor(const std::string &key)
- {
- if (key == "temp")
- return get_mb_temp();
- else if (key == "ref_locked")
- return get_ref_lock();
- else
- throw uhd::lookup_error(
- str(boost::format("Invalid sensor %s requested.") % key));
- }
-
- uhd::sensor_value_t get_mb_temp(void)
- {
- double scale = std::stod(
- e300_get_sysfs_attr(E300_TEMP_SYSFS, "in_temp0_scale"));
- unsigned long raw = std::stoul(
- e300_get_sysfs_attr(E300_TEMP_SYSFS, "in_temp0_raw"));
- unsigned long offset = std::stoul(
- e300_get_sysfs_attr(E300_TEMP_SYSFS, "in_temp0_offset"));
- return sensor_value_t("temp", (raw + offset) * scale / 1000, "C");
- }
-
- uhd::sensor_value_t get_ref_lock(void)
- {
- //PPSLOOP_LOCKED_MASK is asserted in the following cases:
- //- (Time source = GPS or External) AND (Loop is locked and is in fine adj mode)
- //- Time source is Internal
- static const uint32_t PPSLOOP_LOCKED_MASK = 0x04;
- static const uint32_t REFPLL_LOCKED_MASK = 0x20;
-
- const uint32_t status =
- _global_regs->peek32(global_regs::RB32_CORE_MISC);
- bool ref_locked = (status & PPSLOOP_LOCKED_MASK) && (status & REFPLL_LOCKED_MASK);
-
- return sensor_value_t("Ref", ref_locked, "locked", "unlocked");
- }
-
-private:
- global_regs::sptr _global_regs;
-};
-}}}
-
-using namespace uhd::usrp::e300;
-e300_sensor_manager::sptr e300_sensor_manager::make_local(
- global_regs::sptr global_regs)
-{
- return sptr(new e300_sensor_local(global_regs));
-}
-
-#else
-using namespace uhd::usrp::e300;
-e300_sensor_manager::sptr e300_sensor_manager::make_local(
- global_regs::sptr)
-{
- throw uhd::assertion_error("e300_sensor_manager::make_local() !E300_NATIVE");
-}
-#endif
diff --git a/host/lib/usrp/e300/e300_sensor_manager.hpp b/host/lib/usrp/e300/e300_sensor_manager.hpp
deleted file mode 100644
index 8ed09b1eb..000000000
--- a/host/lib/usrp/e300/e300_sensor_manager.hpp
+++ /dev/null
@@ -1,68 +0,0 @@
-//
-// Copyright 2014-2015 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/utils/noncopyable.hpp>
-#include <stdint.h>
-
-#include <uhd/transport/zero_copy.hpp>
-#include <uhd/types/sensors.hpp>
-#include <uhd/utils/byteswap.hpp>
-#include <uhd/usrp/gps_ctrl.hpp>
-#include "e300_global_regs.hpp"
-
-#ifndef INCLUDED_E300_SENSOR_MANAGER_HPP
-#define INCLUDED_E300_SENSOR_MANAGER_HPP
-
-namespace uhd { namespace usrp { namespace e300 {
-
-struct sensor_transaction_t {
- uint32_t which;
- union {
- uint32_t value;
- uint32_t value64;
- };
-};
-
-
-
-enum sensor {ZYNQ_TEMP=0, REF_LOCK=4};
-
-class e300_sensor_manager : uhd::noncopyable
-{
-public:
- typedef boost::shared_ptr<e300_sensor_manager> sptr;
-
- virtual ~e300_sensor_manager() {};
-
- virtual uhd::sensor_value_t get_sensor(const std::string &key) = 0;
- virtual std::vector<std::string> get_sensors(void) = 0;
-
- virtual uhd::sensor_value_t get_mb_temp(void) = 0;
- virtual uhd::sensor_value_t get_ref_lock(void) = 0;
-
-
- static sptr make_proxy(uhd::transport::zero_copy_if::sptr xport);
- static sptr make_local(global_regs::sptr global_regs);
-
- // Note: This is a hack
- static uint32_t pack_float_in_uint32_t(const float &v)
- {
- const uint32_t *cast = reinterpret_cast<const uint32_t*>(&v);
- return *cast;
- }
-
- static float unpack_float_from_uint32_t(const uint32_t &v)
- {
- const float *cast = reinterpret_cast<const float*>(&v);
- return *cast;
- }
-};
-
-
-}}} // namespace
-
-#endif // INCLUDED_E300_SENSOR_MANAGER_HPP
diff --git a/host/lib/usrp/e300/e300_spi.cpp b/host/lib/usrp/e300/e300_spi.cpp
deleted file mode 100644
index e0f25c22f..000000000
--- a/host/lib/usrp/e300/e300_spi.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#include <uhd/config.hpp>
-#include <uhd/exception.hpp>
-#include "e300_spi.hpp"
-
-#ifdef E300_NATIVE
-#include <boost/thread.hpp>
-#include <boost/format.hpp>
-
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <linux/types.h>
-#include <linux/spi/spidev.h>
-
-namespace uhd { namespace usrp { namespace e300 {
-
-class spidev_impl : public spi
-{
-public:
-
- spidev_impl(const std::string &device)
- : _mode(SPI_CPHA),
- _speed(2000000),
- _bits(8),
- _delay(0)
- {
- int ret;
- _fd = open(device.c_str(), O_RDWR);
- if (_fd < 0)
- throw uhd::runtime_error(str(boost::format("Could not open spidev device %s") % device));
-
- ret = ioctl(_fd, SPI_IOC_WR_MODE, &_mode);
- if (ret == -1)
- throw uhd::runtime_error("Could not set spidev mode");
-
- ret = ioctl(_fd, SPI_IOC_RD_MODE, &_mode);
- if (ret == -1)
- throw uhd::runtime_error("Could not get spidev mode");
-
- ret = ioctl(_fd, SPI_IOC_WR_BITS_PER_WORD, &_bits);
- if (ret == -1)
- throw uhd::runtime_error("Could not set spidev bits per word");
-
- ret = ioctl(_fd, SPI_IOC_RD_BITS_PER_WORD, &_bits);
- if (ret == -1)
- throw uhd::runtime_error("Could not get spidev bits per word");
-
- ret = ioctl(_fd, SPI_IOC_WR_MAX_SPEED_HZ, &_speed);
- if (ret == -1)
- throw uhd::runtime_error("Could not set spidev max speed");
-
- ret = ioctl(_fd, SPI_IOC_RD_MAX_SPEED_HZ, &_speed);
- if (ret == -1)
- throw uhd::runtime_error("Could not get spidev max speed");
- }
-
- virtual ~spidev_impl()
- {
- close(_fd);
- }
-
- uint32_t transact_spi(int, const uhd::spi_config_t &,
- uint32_t data, size_t num_bits,
- bool)
- {
- int ret(0);
- struct spi_ioc_transfer tr;
-
- uint8_t *tx_data = reinterpret_cast<uint8_t *>(&data);
-
-
- UHD_ASSERT_THROW(num_bits == 24);
- uint8_t tx[] = {tx_data[2], tx_data[1], tx_data[0]};
-
- uint8_t rx[3];
- tr.tx_buf = (unsigned long) &tx[0];
- tr.rx_buf = (unsigned long) &rx[0];
- tr.len = num_bits >> 3;
- tr.bits_per_word = _bits;
- tr.tx_nbits = 1;
- tr.rx_nbits = 1;
- tr.speed_hz = _speed;
- tr.delay_usecs = _delay;
-
- ret = ioctl(_fd, SPI_IOC_MESSAGE(1), &tr);
- if (ret < 1)
- throw uhd::runtime_error("Could not send spidev message");
-
- return rx[2];
- }
-
-private:
- int _fd;
- uint8_t _mode;
- uint32_t _speed;
- uint8_t _bits;
- uint16_t _delay;
-};
-
-spi::sptr spi::make(const std::string &device)
-{
- return spi::sptr(new spidev_impl(device));
-}
-}}};
-#else
-namespace uhd { namespace usrp { namespace e300 {
-
-spi::sptr spi::make(const std::string &)
-{
- throw uhd::assertion_error("spi::make() !E300_NATIVE");
-}
-}}};
-#endif //E300_NATIVE
diff --git a/host/lib/usrp/e300/e300_spi.hpp b/host/lib/usrp/e300/e300_spi.hpp
deleted file mode 100644
index 0341ae9c4..000000000
--- a/host/lib/usrp/e300/e300_spi.hpp
+++ /dev/null
@@ -1,24 +0,0 @@
-//
-// Copyright 2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_E300_SPI_HPP
-#define INCLUDED_E300_SPI_HPP
-
-#include <uhd/types/serial.hpp>
-
-namespace uhd { namespace usrp { namespace e300 {
-
-class spi : public virtual uhd::spi_iface
-{
-public:
- typedef boost::shared_ptr<spi> sptr;
- static sptr make(const std::string &device);
-};
-
-}}};
-
-#endif /* INCLUDED_E300_SPI_HPP */
diff --git a/host/lib/usrp/e300/e300_sysfs_hooks.cpp b/host/lib/usrp/e300/e300_sysfs_hooks.cpp
deleted file mode 100644
index 81dcff0cb..000000000
--- a/host/lib/usrp/e300/e300_sysfs_hooks.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-//
-// Copyright 2013-2014 Ettus Research LLC
-// Copyright 2018 Ettus Research, a National Instruments Company
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifdef E300_NATIVE
-
-#include <cstdio>
-#include <cstdlib>
-#include <string>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-
-#include <libudev.h>
-
-#include <boost/format.hpp>
-#include <boost/lexical_cast.hpp>
-
-#include <uhd/utils/log.hpp>
-#include <uhd/exception.hpp>
-
-static const std::string E300_AXI_FPGA_SYSFS = "40000000.axi-fpga";
-static const std::string E300_XDEV_SYSFS = "f8007000.ps7-dev-cfg";
-
-std::string e300_get_sysfs_attr(const std::string &node, const std::string &attr)
-{
- udev *udev;
- udev_enumerate *enumerate;
- udev_list_entry *devices, *dev_list_entry;
- udev_device *dev;
- std::string retstring;
-
- udev = udev_new();
-
- if (!udev) {
- throw uhd::lookup_error("Failed to get udev handle.");
- }
-
- enumerate = udev_enumerate_new(udev);
- udev_enumerate_add_match_sysname(enumerate, node.c_str());
- udev_enumerate_scan_devices(enumerate);
- devices = udev_enumerate_get_list_entry(enumerate);
-
- udev_list_entry_foreach(dev_list_entry, devices)
- {
- const char *path;
-
- path = udev_list_entry_get_name(dev_list_entry);
- dev = udev_device_new_from_syspath(udev, path);
-
- retstring = udev_device_get_sysattr_value(dev, attr.c_str());
-
- udev_device_unref(dev);
-
- if (retstring.size())
- break;
- }
-
- udev_enumerate_unref(enumerate);
- udev_unref(udev);
-
- return retstring;
-}
-
-static bool e300_fpga_loaded_successfully(void)
-{
- return boost::lexical_cast<bool>(e300_get_sysfs_attr(E300_XDEV_SYSFS, "prog_done"));
-}
-
-#include "e300_fifo_config.hpp"
-#include <uhd/exception.hpp>
-
-e300_fifo_config_t e300_read_sysfs(void)
-{
-
- if (not e300_fpga_loaded_successfully())
- {
- throw uhd::runtime_error("E300 FPGA load failed!");
- }
-
- e300_fifo_config_t config;
-
- config.buff_length = std::stoul(
- e300_get_sysfs_attr(E300_AXI_FPGA_SYSFS, "buffer_length"));
- config.ctrl_length = std::stoul(
- e300_get_sysfs_attr(E300_AXI_FPGA_SYSFS, "control_length"));
- config.phys_addr = std::stoul(
- e300_get_sysfs_attr(E300_AXI_FPGA_SYSFS, "phys_addr"));
-
- return config;
-}
-
-#else //E300_NATIVE
-
-#include "e300_fifo_config.hpp"
-#include <uhd/exception.hpp>
-
-e300_fifo_config_t e300_read_sysfs(void)
-{
- throw uhd::assertion_error("e300_read_sysfs() !E300_NATIVE");
-}
-
-std::string e300_get_sysfs_attr(const std::string &, const std::string &)
-{
- throw uhd::assertion_error("e300_sysfs_attr() !E300_NATIVE");
-}
-
-#endif //E300_NATIVE
diff --git a/host/lib/usrp/e300/e3xx_radio_ctrl_impl.cpp b/host/lib/usrp/e300/e3xx_radio_ctrl_impl.cpp
deleted file mode 100644
index 787faf6df..000000000
--- a/host/lib/usrp/e300/e3xx_radio_ctrl_impl.cpp
+++ /dev/null
@@ -1,770 +0,0 @@
-//
-// Copyright 2015-2016 Ettus Research
-//
-// 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 <http://www.gnu.org/licenses/>.
-//
-
-#include "e3xx_radio_ctrl_impl.hpp"
-#include "e300_defaults.hpp"
-#include "e300_regs.hpp"
-#include <boost/make_shared.hpp>
-#include <uhd/usrp/dboard_iface.hpp>
-#include <uhd/rfnoc/node_ctrl_base.hpp>
-#include <uhd/utils/log.hpp>
-#include <boost/algorithm/string.hpp>
-#include <boost/make_shared.hpp>
-
-using namespace uhd;
-using namespace uhd::rfnoc;
-using namespace uhd::usrp::e300;
-using uhd::usrp::dboard_iface;
-
-//! mapping of frontend to radio perif index
-static const size_t FE0 = 1;
-static const size_t FE1 = 0;
-
-/****************************************************************************
- * Structors
- ***************************************************************************/
-UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(e3xx_radio_ctrl)
-{
- UHD_RFNOC_BLOCK_TRACE() << "e3xx_radio_ctrl_impl::ctor() " << std::endl;
-
- ////////////////////////////////////////////////////////////////////
- // Set up peripherals
- ////////////////////////////////////////////////////////////////////
- for (size_t i = 0; i < _get_num_radios(); i++) {
- if (i == 0) {
- _spi = spi_core_3000::make(_get_ctrl(i), regs::sr_addr(regs::SPI), regs::RB_SPI);
- _spi->set_divider(6);
- }
- _e3xx_perifs[i].atr = usrp::gpio_atr::gpio_atr_3000::make_write_only(_get_ctrl(i), regs::sr_addr(regs::GPIO));
- _e3xx_perifs[i].leds = usrp::gpio_atr::gpio_atr_3000::make_write_only(_get_ctrl(i), regs::sr_addr(regs::LEDS));
- _e3xx_perifs[i].leds->set_atr_mode(usrp::gpio_atr::MODE_ATR, usrp::gpio_atr::gpio_atr_3000::MASK_SET_ALL);
- }
-
- ////////////////////////////////////////////////////////////////////
- // Time source
- ////////////////////////////////////////////////////////////////////
- _tree->create<std::string>("time_source/value")
- .add_coerced_subscriber(boost::bind(&e3xx_radio_ctrl_impl::_update_time_source, this, _1))
- .set(DEFAULT_TIME_SRC);
-#ifdef E300_GPSD
- static const std::vector<std::string> time_sources = boost::assign::list_of("none")("internal")("external")("gpsdo");
-#else
- static const std::vector<std::string> time_sources = boost::assign::list_of("none")("internal")("external");
-#endif
- _tree->create<std::vector<std::string> >("time_source/options").set(time_sources);
-
- ////////////////////////////////////////////////////////////////////
- // create RF frontend interfacing
- ////////////////////////////////////////////////////////////////////
- {
- const fs_path codec_path = fs_path("rx_codecs") / "A";
- _tree->create<std::string>(codec_path / "name").set("E3x0 RX dual ADC");
- _tree->create<int>(codec_path / "gains"); //empty cuz gains are in frontend
- }
- {
- const fs_path codec_path = fs_path("tx_codecs") / "A";
- _tree->create<std::string>(codec_path / "name").set("E3x0 TX dual DAC");
- _tree->create<int>(codec_path / "gains"); //empty cuz gains are in frontend
- }
-
- ////////////////////////////////////////////////////////////////////
- // internal gpios
- ////////////////////////////////////////////////////////////////////
- UHD_RFNOC_BLOCK_TRACE() << " Creating internal GPIOs..." << std::endl;
-
- usrp::gpio_atr::gpio_atr_3000::sptr fp_gpio = usrp::gpio_atr::gpio_atr_3000::make(
- get_ctrl_iface(0),
- regs::sr_addr(regs::FP_GPIO),
- regs::RB_FP_GPIO
- );
- for (const auto& attr : usrp::gpio_atr::gpio_attr_map) {
- switch (attr.first) {
- case usrp::gpio_atr::GPIO_SRC:
- _tree->create<std::vector<std::string>>(fs_path("gpio") / "INT0" / attr.second)
- .set(std::vector<std::string>(32, usrp::gpio_atr::default_attr_value_map.at(attr.first)))
- .add_coerced_subscriber([this](const std::vector<std::string>&){
- throw uhd::runtime_error("This device does not support setting the GPIO_SRC attribute.");
- });
- break;
- case usrp::gpio_atr::GPIO_CTRL:
- case usrp::gpio_atr::GPIO_DDR:
- _tree->create<std::vector<std::string>>(fs_path("gpio") / "INT0" / attr.second)
- .set(std::vector<std::string>(32, usrp::gpio_atr::default_attr_value_map.at(attr.first)))
- .add_coerced_subscriber([this, fp_gpio, attr](const std::vector<std::string> str_val){
- uint32_t val = 0;
- for(size_t i = 0 ; i < str_val.size() ; i++){
- val += usrp::gpio_atr::gpio_attr_value_pair.at(attr.second).at(str_val[i])<<i;
- }
- fp_gpio->set_gpio_attr(attr.first, val);
- });
- break;
- case usrp::gpio_atr::GPIO_READBACK:
- _tree->create<uint8_t>(fs_path("gpio") / "INT0" / "READBACK")
- .set_publisher([this, fp_gpio](){
- return fp_gpio->read_gpio();
- });
- break;
- default:
- _tree->create<uint32_t>(fs_path("gpio") / "INT0" / attr.second)
- .set(0)
- .add_coerced_subscriber([this, fp_gpio, attr](const uint32_t val){
- fp_gpio->set_gpio_attr(attr.first, val);
- });
- }
- }
-
- ////////////////////////////////////////////////////////////////////
- // Tick rate
- ////////////////////////////////////////////////////////////////////
- UHD_RFNOC_BLOCK_TRACE() << " Setting tick rate..." << std::endl;
- _tree->access<double>("tick_rate")
- .add_coerced_subscriber(boost::bind(&e3xx_radio_ctrl_impl::set_rate, this, _1))
- .set_publisher(boost::bind(&e3xx_radio_ctrl_impl::get_rate, this))
- ;
-}
-
-e3xx_radio_ctrl_impl::~e3xx_radio_ctrl_impl()
-{
- const std::string _radio_slot = "A";
- // Tear down our part of the tree:
- _tree->remove(fs_path("rx_codecs" / _radio_slot));
- _tree->remove(fs_path("tx_codecs" / _radio_slot));
- for (size_t i = 0; i < _get_num_radios(); i++) {
- if (_tree->exists(fs_path("tx_dsps") / i)) {
- _tree->remove(fs_path("tx_dsps") / i);
- }
- if (_tree->exists(fs_path("rx_dsps") / i)) {
- _tree->remove(fs_path("rx_dsps") / i);
- }
- }
- for (const auto attr : usrp::gpio_atr::gpio_attr_map) {
- const auto gpio_fs_path = fs_path("gpio") / "INT0" / attr.second;
- if (_tree->exists(gpio_fs_path)) {
- _tree->remove(gpio_fs_path);
- }
- }
-}
-
-/****************************************************************************
- * API calls
- ***************************************************************************/
-double e3xx_radio_ctrl_impl::set_rate(double rate)
-{
- //UHD_LOGGER_DEBUG("E300") << "Setting SPI divider to " << ceil(rate/AD9361_SPI_RATE) << "\n";
- //_spi->set_divider(ceil(rate/AD9361_SPI_RATE)); // ceil() to prevent less than 1 rounding to 0
- UHD_LOGGER_DEBUG("E300") << "Asking for clock rate " << rate/1e6 << " MHz\n";
- double actual_tick_rate = _codec_ctrl->set_clock_rate(rate);
- UHD_LOGGER_DEBUG("E300") << "Actually got clock rate " << actual_tick_rate/1e6 << " MHz\n";
-
- actual_tick_rate = radio_ctrl_impl::set_rate(actual_tick_rate);
-
- if (not check_radio_config()) {
- throw std::runtime_error(str(
- boost::format("[%s]: Invalid radio configuration.")
- % unique_id()
- ));
- }
-
- return actual_tick_rate;
-}
-
-/*! Select TX antenna \p for channel \p chan.
- */
-void e3xx_radio_ctrl_impl::set_tx_antenna(const std::string &ant, const size_t chan)
-{
- std::lock_guard<std::mutex> lock(_mutex);
- if (ant != "TX/RX")
- throw uhd::value_error("Unknown TX antenna option: " + ant);
-
- radio_ctrl_impl::set_tx_antenna(ant, chan);
-}
-
-/*! Select RX antenna \p for channel \p chan.
- */
-void e3xx_radio_ctrl_impl::set_rx_antenna(const std::string &ant, const size_t chan)
-{
- std::lock_guard<std::mutex> lock(_mutex);
- if (ant != "TX/RX" and ant != "RX2")
- throw uhd::value_error("Unknown RX antenna option: " + ant);
-
- radio_ctrl_impl::set_rx_antenna(ant, chan);
- this->_update_atrs();
- this->_update_atr_leds(_e3xx_perifs[chan].leds, ant);
-}
-
-double e3xx_radio_ctrl_impl::set_tx_frequency(const double freq, const size_t)
-{
- return _tree->access<double>(fs_path("dboards/A/tx_frontends/A/freq/value")).set(freq).get();
-}
-
-double e3xx_radio_ctrl_impl::set_rx_frequency(const double freq, const size_t)
-{
- return _tree->access<double>(fs_path("dboards/A/rx_frontends/A/freq/value")).set(freq).get();
-}
-
-double e3xx_radio_ctrl_impl::set_tx_gain(const double gain, const size_t chan)
-{
- const std::string fe_side = (chan == 0) ? "A" : "B";
- double new_gain = _tree->access<double>(fs_path("dboards/A/tx_frontends/" + fe_side + "/gains/PGA/value")).set(gain).get();
- return radio_ctrl_impl::set_tx_gain(new_gain, chan);
-}
-
-double e3xx_radio_ctrl_impl::set_rx_gain(const double gain, const size_t chan)
-{
- const std::string fe_side = (chan == 0) ? "A" : "B";
- double new_gain = _tree->access<double>(fs_path("dboards/A/rx_frontends/" + fe_side + "/gains/PGA/value")).set(gain).get();
- return radio_ctrl_impl::set_rx_gain(new_gain, chan);
-}
-
-double e3xx_radio_ctrl_impl::set_rx_bandwidth(const double bandwidth, const size_t chan)
-{
- const std::string fe_side = (chan == 0) ? "A" : "B";
- double new_bw = _tree->access<double>(fs_path("dboards/A/rx_frontends/" + fe_side + "/bandwidth/value")).set(bandwidth).get();
- return radio_ctrl_impl::set_rx_bandwidth(new_bw, chan);
-}
-
-double e3xx_radio_ctrl_impl::get_tx_gain(const size_t chan)
-{
- const std::string fe_side = (chan == 0) ? "A" : "B";
- return _tree->access<double>(fs_path("dboards/A/tx_frontends/" + fe_side + "/gains/PGA/value")).get();
-}
-
-double e3xx_radio_ctrl_impl::get_rx_gain(const size_t chan)
-{
- const std::string fe_side = (chan == 0) ? "A" : "B";
- return _tree->access<double>(fs_path("dboards/A/rx_frontends/" + fe_side + "/gains/PGA/value")).get();
-}
-
-double e3xx_radio_ctrl_impl::get_rx_bandwidth(const size_t chan)
-{
- const std::string fe_side = (chan == 0) ? "A" : "B";
- return _tree->access<double>(fs_path("dboards/A/rx_frontends/" + fe_side + "/bandwidth/value")).get();
-}
-
-std::vector<std::string> e3xx_radio_ctrl_impl::get_gpio_banks() const
-{
- std::vector<std::string> banks = boost::assign::list_of("INT0");
- return banks;
-}
-
-void e3xx_radio_ctrl_impl::set_gpio_attr(
- const std::string &bank,
- const std::string &attr,
- const uint32_t value,
- const uint32_t mask
-) {
- if (bank == "INT0") {
- const uint32_t current = _tree->access<uint32_t>(fs_path("gpio") / bank / attr).get();
- const uint32_t new_value = (current & ~mask) | (value & mask);
- _tree->access<uint32_t>(fs_path("gpio") / bank / attr).set(new_value);
- return;
- }
-}
-
-uint32_t e3xx_radio_ctrl_impl::get_gpio_attr(
- const std::string &bank,
- const std::string &attr
-) {
- if (bank == "INT0") {
- return uint32_t(_tree->access<uint64_t>(fs_path("gpio") / bank / attr).get());
- }
- return 0;
-}
-
-size_t e3xx_radio_ctrl_impl::get_chan_from_dboard_fe(const std::string &fe, const direction_t)
-{
- return (fe == "A") ? 0 : 1;
-}
-
-std::string e3xx_radio_ctrl_impl::get_dboard_fe_from_chan(const size_t chan, const direction_t)
-{
- return (chan == 0) ? "A" : "B";
-}
-
-/****************************************************************************
- * Radio control and setup
- ***************************************************************************/
-void e3xx_radio_ctrl_impl::setup_radio(uhd::usrp::ad9361_ctrl::sptr safe_codec_ctrl)
-{
- {
- std::lock_guard<std::mutex> lock(_mutex);
- if (_codec_ctrl) {
- throw std::runtime_error("Attempting to set up radio twice!");
- }
- }
-
- ////////////////////////////////////////////////////////////////////
- // Create timed interface
- ////////////////////////////////////////////////////////////////////
- _codec_ctrl = safe_codec_ctrl;
- _codec_mgr = uhd::usrp::ad936x_manager::make(_codec_ctrl, _get_num_radios());
-
- ////////////////////////////////////////////////////////////////////
- // setup radios
- ////////////////////////////////////////////////////////////////////
- for (size_t chan = 0; chan < _get_num_radios(); chan++) {
- _setup_radio_channel(chan);
- }
- // Loopback test
- for (size_t chan = 0; chan < _get_num_radios(); chan++) {
- _codec_mgr->loopback_self_test(
- [this, chan](const uint32_t value){
- this->sr_write(regs::CODEC_IDLE, value, chan);
- },
- [this, chan](){
- return this->user_reg_read64(regs::RB_CODEC_READBACK, chan);
- }
- );
- }
-
- this->_update_enables();
-}
-
-void e3xx_radio_ctrl_impl::_setup_radio_channel(const size_t chan)
-{
- const fs_path rx_dsp_path = fs_path("rx_dsps") / chan;
- _tree->create<stream_cmd_t>(rx_dsp_path / "stream_cmd")
- .add_coerced_subscriber(boost::bind(&radio_ctrl_impl::issue_stream_cmd, this, _1, chan));
-
- ////////////////////////////////////////////////////////////////////
- // add some dummy nodes on the prop tree (FIXME remove these)
- ////////////////////////////////////////////////////////////////////
- const fs_path tx_dsp_path = fs_path("tx_dsps") / chan;
- _tree->create<double>(tx_dsp_path / "freq/value").set(0.0);
- _tree->create<meta_range_t>(tx_dsp_path / "freq/range").set(meta_range_t(0.0, 0.0, 0.0));
- _tree->create<double>(rx_dsp_path / "freq/value").set(0.0);
- _tree->create<meta_range_t>(rx_dsp_path / "freq/range").set(meta_range_t(0.0, 0.0, 0.0));
- _tree->create<double>(tx_dsp_path / "rate/value")
- .add_coerced_subscriber(boost::bind(&e3xx_radio_ctrl_impl::set_rate, this, _1))
- .set_publisher(boost::bind(&radio_ctrl_impl::get_rate, this))
- ;
- _tree->create<double>(rx_dsp_path / "rate/value")
- .add_coerced_subscriber(boost::bind(&e3xx_radio_ctrl_impl::set_rate, this, _1))
- .set_publisher(boost::bind(&radio_ctrl_impl::get_rate, this))
- ;
-
- ////////////////////////////////////////////////////////////////////
- // create RF frontend interfacing
- ////////////////////////////////////////////////////////////////////
- static const std::vector<direction_t> dirs = boost::assign::list_of(RX_DIRECTION)(TX_DIRECTION);
- BOOST_FOREACH(direction_t dir, dirs) {
- const std::string x = (dir == RX_DIRECTION) ? "rx" : "tx";
- const std::string key = boost::to_upper_copy(x) + std::string(((chan == FE0)? "1" : "2"));
- const fs_path rf_fe_path
- = fs_path("dboards") / "A" / (x + "_frontends") / ((chan == 0) ? "A" : "B");
-
- // This will connect all the AD936x-specific items
- _codec_mgr->populate_frontend_subtree(
- _tree->subtree(rf_fe_path), key, dir
- );
-
- // This will connect all the e3xx_radio_ctrl-specific items
- _tree->create<sensor_value_t>(rf_fe_path / "sensors" / "lo_locked")
- .set_publisher(boost::bind(&e3xx_radio_ctrl_impl::_get_fe_pll_lock, this, dir == TX_DIRECTION))
- ;
- const double freq = _tree->access<double>(rf_fe_path / "freq" / "value")
- .add_coerced_subscriber(boost::bind(&e3xx_radio_ctrl_impl::_update_fe_lo_freq, this, key, _1)).get()
- ;
- // Set frequency in parent (to be used to update ATR values later)
- if (dir == RX_DIRECTION) {
- radio_ctrl_impl::set_rx_frequency(freq, chan);
- } else {
- radio_ctrl_impl::set_tx_frequency(freq, chan);
- }
-
- // Antenna Setup
- if (dir == RX_DIRECTION) {
- static const std::vector<std::string> ants = boost::assign::list_of("TX/RX")("RX2");
- _tree->create<std::vector<std::string> >(rf_fe_path / "antenna" / "options").set(ants);
- _tree->create<std::string>(rf_fe_path / "antenna" / "value")
- .add_coerced_subscriber(boost::bind(&e3xx_radio_ctrl_impl::set_rx_antenna, this, _1, chan))
- .set_publisher(boost::bind(&e3xx_radio_ctrl_impl::get_rx_antenna, this, chan));
- // Set default in parent (to be used to update ATR values later)
- radio_ctrl_impl::set_rx_antenna("RX2", chan);
- // Set up LEDs for default antenna
- _update_atr_leds(_e3xx_perifs[chan].leds, "RX2");
- }
- else if (dir == TX_DIRECTION) {
- static const std::vector<std::string> ants(1, "TX/RX");
- _tree->create<std::vector<std::string> >(rf_fe_path / "antenna" / "options").set(ants);
- _tree->create<std::string>(rf_fe_path / "antenna" / "value")
- .add_coerced_subscriber(boost::bind(&e3xx_radio_ctrl_impl::set_tx_antenna, this, _1, chan))
- .set_publisher(boost::bind(&e3xx_radio_ctrl_impl::get_tx_antenna, this, chan))
- .set("TX/RX");
- }
- }
-}
-
-void e3xx_radio_ctrl_impl::_reset_radio(void)
-{
- std::lock_guard<std::mutex> lock(_mutex);
- _misc.radio_rst = 1;
- _update_gpio_state();
- boost::this_thread::sleep(boost::posix_time::milliseconds(10));
- _misc.radio_rst = 0;
- _update_gpio_state();
- boost::this_thread::sleep(boost::posix_time::milliseconds(10));
-}
-
-/****************************************************************************
- * Helpers
- ***************************************************************************/
-bool e3xx_radio_ctrl_impl::check_radio_config()
-{
- const size_t num_rx = _is_streamer_active(RX_DIRECTION, FE0) + _is_streamer_active(RX_DIRECTION, FE1);
- const size_t num_tx = _is_streamer_active(TX_DIRECTION, FE0) + _is_streamer_active(TX_DIRECTION, FE1);
- _enforce_tick_rate_limits(
- std::max(num_rx, num_tx),
- get_tick_rate()
- );
-
- this->_update_enables();
- return true;
-}
-
-void e3xx_radio_ctrl_impl::_enforce_tick_rate_limits(
- const size_t chan_count,
- const double tick_rate
-) {
- const size_t max_chans = 2;
- if (chan_count > max_chans) {
- throw uhd::value_error(boost::str(
- boost::format("cannot not setup %d channels per direction (maximum is %d)")
- % chan_count
- % max_chans
- ));
- } else {
- const double max_tick_rate = uhd::usrp::ad9361_device_t::AD9361_MAX_CLOCK_RATE / ((chan_count <= 1) ? 1 : 2);
- if (tick_rate - max_tick_rate >= 1.0)
- {
- throw uhd::value_error(boost::str(
- boost::format("current master clock rate (%.6f MHz) exceeds maximum possible master clock rate (%.6f MHz) when using %d channels")
- % (tick_rate/1e6)
- % (max_tick_rate/1e6)
- % chan_count
- ));
- }
- // TODO minimum rate check
- }
-}
-
-/****************************************************************************
- * Peripheral controls
- ***************************************************************************/
-void e3xx_radio_ctrl_impl::_update_fe_lo_freq(const std::string &fe, const double freq)
-{
- if (fe[0] == 'R') {
- for (size_t i = 0; i < _get_num_radios(); i++) {
- radio_ctrl_impl::set_rx_frequency(freq, i);
- }
- }
- if (fe[0] == 'T') {
- for (size_t i = 0; i < _get_num_radios(); i++) {
- radio_ctrl_impl::set_tx_frequency(freq, i);
- }
- }
- this->_update_atrs();
-}
-
-void e3xx_radio_ctrl_impl::_update_atrs(void)
-{
- for (size_t instance = 0; instance < _get_num_radios(); instance++)
- {
- // if we're not ready, no point ...
- if (not _e3xx_perifs[instance].atr)
- return;
-
- const bool rx_ant_rx2 = get_rx_antenna(instance) == "RX2";
- const double rx_freq = get_rx_frequency(instance);
- const double tx_freq = get_tx_frequency(instance);
- const bool rx_low_band = rx_freq < 2.6e9;
- const bool tx_low_band = tx_freq < 2940.0e6;
-
- // VCRX
- uint32_t vcrx_v1_rxing = 1;
- uint32_t vcrx_v2_rxing = 0;
- uint32_t vcrx_v1_txing = 1;
- uint32_t vcrx_v2_txing = 0;
-
- if (rx_low_band) {
- vcrx_v1_rxing = rx_ant_rx2 ? 0 : 1;
- vcrx_v2_rxing = rx_ant_rx2 ? 1 : 0;
- vcrx_v1_txing = 0;
- vcrx_v2_txing = 1;
- } else {
- vcrx_v1_rxing = rx_ant_rx2 ? 1 : 0;
- vcrx_v2_rxing = rx_ant_rx2 ? 0 : 1;
- vcrx_v1_txing = 1;
- vcrx_v2_txing = 0;
- }
-
- // VCTX
- uint32_t vctxrx_v1_rxing = 0;
- uint32_t vctxrx_v2_rxing = 1;
- uint32_t vctxrx_v1_txing = 0;
- uint32_t vctxrx_v2_txing = 1;
-
- if (tx_low_band) {
- vctxrx_v1_rxing = rx_ant_rx2 ? 1 : 0;
- vctxrx_v2_rxing = rx_ant_rx2 ? 0 : 1;
- vctxrx_v1_txing = 1;
- vctxrx_v2_txing = 0;
- } else {
- vctxrx_v1_rxing = rx_ant_rx2 ? 1 : 0;
- vctxrx_v2_rxing = rx_ant_rx2 ? 0 : 1;
- vctxrx_v1_txing = 1;
- vctxrx_v2_txing = 1;
- }
-
- //swapped for routing reasons, reswap it here
- if (instance == 1) {
- std::swap(vctxrx_v1_rxing, vctxrx_v2_rxing);
- std::swap(vctxrx_v1_txing, vctxrx_v2_txing);
- }
-
- uint32_t tx_enable_a = (!tx_low_band) ? 1 : 0;
- uint32_t tx_enable_b = (tx_low_band) ? 1 : 0;
-
- /* Set RX / TX band selects */
- uint32_t rx_band_select_a = 0;
- uint32_t rx_band_select_b = 0;
- uint32_t rx_band_select_c = 0;
- uint32_t tx_band_select = 0;
-
- if (instance == 0) {
- // RX
- if (rx_freq < 450e6) {
- rx_band_select_a = 5; // 3'b101
- rx_band_select_b = 0; // 2'bXX -- Don't care
- rx_band_select_c = 1; // 2'b01
- } else if (rx_freq < 700e6) {
- rx_band_select_a = 3; // 3'b011
- rx_band_select_b = 0; // 2'bXX -- Don't care
- rx_band_select_c = 3; // 2'b11
- } else if (rx_freq < 1200e6) {
- rx_band_select_a = 1; // 3'b001
- rx_band_select_b = 0; // 2'bXX -- Don't care
- rx_band_select_c = 2; // 2'b10
- } else if (rx_freq < 1800e6) {
- rx_band_select_a = 0; // 3'b000
- rx_band_select_b = 1; // 2'b01
- rx_band_select_c = 0; // 2'bXX -- Don't care
- } else if (rx_freq < 2350e6){
- rx_band_select_a = 2; // 3'b010
- rx_band_select_b = 3; // 2'b11
- rx_band_select_c = 0; // 2'bXX -- Don't care
- } else if (rx_freq < 2600e6){
- rx_band_select_a = 4; // 3'b100
- rx_band_select_b = 2; // 2'b10
- rx_band_select_c = 0; // 2'bXX -- Don't care
- } else { // >= 2600e6
- rx_band_select_a = 5; // 3'bXX -- Don't care
- rx_band_select_b = 0; // 2'bXX -- Don't care
- rx_band_select_c = 1; // 2'bXX -- Don't care
- }
- } else if (instance == 1) {
- if (rx_freq < 450e6) {
- rx_band_select_a = 4; // 3'b100
- rx_band_select_b = 0; // 2'bXX -- Don't care
- rx_band_select_c = 2; // 2'b10
- } else if (rx_freq < 700e6) {
- rx_band_select_a = 2; // 3'b010
- rx_band_select_b = 0; // 2'bXX -- Don't care
- rx_band_select_c = 3; // 2'b11
- } else if (rx_freq < 1200e6) {
- rx_band_select_a = 0; // 3'b000
- rx_band_select_b = 0; // 2'bXX -- Don't care
- rx_band_select_c = 1; // 2'b01
- } else if (rx_freq < 1800e6) {
- rx_band_select_a = 1; // 3'b001
- rx_band_select_b = 2; // 2'b10
- rx_band_select_c = 0; // 2'bXX -- Don't care
- } else if (rx_freq < 2350e6){
- rx_band_select_a = 3; // 3'b011
- rx_band_select_b = 3; // 2'b11
- rx_band_select_c = 0; // 2'bXX -- Don't care
- } else if (rx_freq < 2600e6){
- rx_band_select_a = 5; // 3'b101
- rx_band_select_b = 1; // 2'b01
- rx_band_select_c = 0; // 2'bXX -- Don't care
- } else { // >= 2600e6
- rx_band_select_a = 5; // 3'bXX -- Don't care
- rx_band_select_b = 0; // 2'bXX -- Don't care
- rx_band_select_c = 1; // 2'bXX -- Don't care
- }
- } else {
- UHD_THROW_INVALID_CODE_PATH();
- }
-
- // TX band selects are the same for both radio frontends
- if (tx_freq < 117.7e6)
- tx_band_select = 7; // 3'b111
- else if (tx_freq < 178.2e6)
- tx_band_select = 6; // 3'b110
- else if (tx_freq < 284.3e6)
- tx_band_select = 5; // 3'b101
- else if (tx_freq < 453.7e6)
- tx_band_select = 4; // 3'b100
- else if (tx_freq < 723.8e6)
- tx_band_select = 3; // 3'b011
- else if (tx_freq < 1154.9e6)
- tx_band_select = 2; // 3'b010
- else if (tx_freq < 1842.6e6)
- tx_band_select = 1; // 3'b001
- else if (tx_freq < 2940.0e6)
- tx_band_select = 0; // 3'b000
- else // > 2940.0e6
- tx_band_select = 7; // 3'bXXX -- Don't care, set to lowest band
-
- const uint32_t rx_selects = 0
- | (vcrx_v1_rxing << VCRX_V1)
- | (vcrx_v2_rxing << VCRX_V2)
- | (vctxrx_v1_rxing << VCTXRX_V1)
- | (vctxrx_v2_rxing << VCTXRX_V2)
- ;
- const uint32_t tx_selects = 0
- | (vcrx_v1_txing << VCRX_V1)
- | (vcrx_v2_txing << VCRX_V2)
- | (vctxrx_v1_txing << VCTXRX_V1)
- | (vctxrx_v2_txing << VCTXRX_V2)
- ;
- const uint32_t tx_enables = 0
- | (tx_enable_a << TX_ENABLEA)
- | (tx_enable_b << TX_ENABLEB)
- ;
- const uint32_t rxtx_band_selects = 0
- | (rx_band_select_a << RX_BANDSEL)
- | (rx_band_select_b << RXB_BANDSEL)
- | (rx_band_select_c << RXC_BANDSEL)
- | (tx_band_select << TX_BANDSEL)
- ;
-
- // Form register values;
- uint32_t oo_reg = rx_selects | rxtx_band_selects;
- uint32_t rx_reg = rx_selects | rxtx_band_selects;
- uint32_t tx_reg = tx_selects | tx_enables | rxtx_band_selects;
- uint32_t fd_reg = tx_selects | tx_enables | rxtx_band_selects; //tx selects dominate in fd mode
-
- //add tx enables based on fe enable
- tx_reg |= tx_enables;
- fd_reg |= tx_enables;
-
- usrp::gpio_atr::gpio_atr_3000::sptr atr = _e3xx_perifs[instance].atr;
- atr->set_atr_reg(usrp::gpio_atr::ATR_REG_IDLE, oo_reg);
- atr->set_atr_reg(usrp::gpio_atr::ATR_REG_RX_ONLY, rx_reg);
- atr->set_atr_reg(usrp::gpio_atr::ATR_REG_TX_ONLY, tx_reg);
- atr->set_atr_reg(usrp::gpio_atr::ATR_REG_FULL_DUPLEX, fd_reg);
- }
-}
-
-void e3xx_radio_ctrl_impl::_update_atr_leds(usrp::gpio_atr::gpio_atr_3000::sptr leds, const std::string &rx_ant)
-{
- const bool is_txrx = (rx_ant == "TX/RX");
- const int rx_led = (1 << 2);
- const int tx_led = (1 << 1);
- const int txrx_led = (1 << 0);
- using namespace uhd::usrp::gpio_atr;
- leds->set_atr_reg(ATR_REG_IDLE, 0);
- leds->set_atr_reg(ATR_REG_RX_ONLY, is_txrx ? txrx_led : rx_led);
- leds->set_atr_reg(ATR_REG_TX_ONLY, tx_led);
- leds->set_atr_reg(ATR_REG_FULL_DUPLEX, rx_led | tx_led);
-}
-
-void e3xx_radio_ctrl_impl::_update_gpio_state(void)
-{
- UHD_RFNOC_BLOCK_TRACE() << "e3xx_radio_ctrl_impl::_update_gpio_state() " << std::endl;
- uint32_t misc_reg = 0
- | (_misc.pps_sel << gpio_t::PPS_SEL)
- | (_misc.mimo << gpio_t::MIMO)
- | (_misc.radio_rst << gpio_t::RADIO_RST);
- _tree->access<uint32_t>("global_regs/misc").set(misc_reg);
-}
-
-void e3xx_radio_ctrl_impl::_update_enables(void)
-{
- std::lock_guard<std::mutex> lock(_mutex);
- UHD_RFNOC_BLOCK_TRACE() << "e3xx_radio_ctrl_impl::_update_enables() " << std::endl;
- if (not _codec_ctrl) {
- UHD_LOGGER_WARNING("E300") << "Attempting to access CODEC controls before setting up the radios." << std::endl;
- return;
- }
-
- const size_t num_rx = _is_streamer_active(RX_DIRECTION, FE0) + _is_streamer_active(RX_DIRECTION, FE1);
- const size_t num_tx = _is_streamer_active(TX_DIRECTION, FE0) + _is_streamer_active(TX_DIRECTION, FE1);
-
- const bool mimo = (num_rx == 2) or (num_tx == 2);
-
- // This currently doesn't work with GNU Radio, so leave it uncommented
- //if ((num_tx + num_rx) == 3)
- // throw uhd::runtime_error("e300: 2 RX 1 TX and 1 RX 2 TX configurations not possible");
-
- //setup the active chains in the codec
- if ((num_rx + num_tx) == 0) {
- // Ensure at least one RX chain is enabled so AD9361 outputs a sample clock
- _codec_ctrl->set_active_chains(false, false, true, false);
- } else {
- _codec_ctrl->set_active_chains(
- _is_streamer_active(TX_DIRECTION, FE0),
- _is_streamer_active(TX_DIRECTION, FE1),
- _is_streamer_active(RX_DIRECTION, FE0),
- _is_streamer_active(RX_DIRECTION, FE1)
- );
- }
-
- // Set radio data direction register cleared due to reset
- for (size_t instance = 0; instance < _get_num_radios(); instance++)
- {
- _e3xx_perifs[instance].atr->set_gpio_ddr(usrp::gpio_atr::DDR_OUTPUT, 0xFFFFFFFF);
- }
-
- //figure out if mimo is enabled based on new state
- _misc.mimo = (mimo) ? 1 : 0;
- _update_gpio_state();
-
- //atrs change based on enables
- _update_atrs();
-}
-
-void e3xx_radio_ctrl_impl::_update_time_source(const std::string &source)
-{
- std::lock_guard<std::mutex> lock(_mutex);
- UHD_LOGGER_DEBUG("E300") << boost::format("Setting time source to %s") % source << std::endl;
- if (source == "none" or source == "internal") {
- _misc.pps_sel = global_regs::PPS_INT;
-#ifdef E300_GPSD
- } else if (source == "gpsdo") {
- _misc.pps_sel = global_regs::PPS_GPS;
-#endif
- } else if (source == "external") {
- _misc.pps_sel = global_regs::PPS_EXT;
- } else {
- throw uhd::key_error("update_time_source: unknown source: " + source);
- }
- _update_gpio_state();
-}
-
-uhd::sensor_value_t e3xx_radio_ctrl_impl::_get_fe_pll_lock(const bool is_tx)
-{
- const uint32_t st = _tree->access<uint32_t>("global_regs/pll").get();
- const bool locked = is_tx ? ((st & 0x1) > 0) : ((st & 0x2) > 0);
- return sensor_value_t("LO", locked, "locked", "unlocked");
-}
-
-/****************************************************************************
- * Register block
- ***************************************************************************/
-UHD_RFNOC_BLOCK_REGISTER(e3xx_radio_ctrl, "E3XXRadio");
diff --git a/host/lib/usrp/e300/e3xx_radio_ctrl_impl.hpp b/host/lib/usrp/e300/e3xx_radio_ctrl_impl.hpp
deleted file mode 100644
index 390b0929c..000000000
--- a/host/lib/usrp/e300/e3xx_radio_ctrl_impl.hpp
+++ /dev/null
@@ -1,149 +0,0 @@
-//
-// Copyright 2015-2016 Ettus Research
-//
-// 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 <http://www.gnu.org/licenses/>.
-//
-
-#ifndef INCLUDED_LIBUHD_RFNOC_E3XX_RADIO_CTRL_IMPL_HPP
-#define INCLUDED_LIBUHD_RFNOC_E3XX_RADIO_CTRL_IMPL_HPP
-
-#include "e300_global_regs.hpp"
-#include <uhdlib/usrp/cores/spi_core_3000.hpp>
-#include <uhdlib/usrp/common/ad9361_ctrl.hpp>
-#include <uhdlib/usrp/common/ad936x_manager.hpp>
-#include <uhdlib/rfnoc/radio_ctrl_impl.hpp>
-#include <uhd/usrp/gpio_defs.hpp>
-
-namespace uhd {
- namespace rfnoc {
-
-/*! \brief Provide access to an E3XX radio.
- */
-class e3xx_radio_ctrl_impl : public radio_ctrl_impl
-{
-public:
- /************************************************************************
- * Structors
- ***********************************************************************/
- UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR_DECL(e3xx_radio_ctrl)
- virtual ~e3xx_radio_ctrl_impl();
-
- /************************************************************************
- * API calls
- ***********************************************************************/
- double set_rate(double rate);
- void set_tx_antenna(const std::string &ant, const size_t chan);
- void set_rx_antenna(const std::string &ant, const size_t chan);
-
- double set_tx_frequency(const double freq, const size_t chan);
- double set_rx_frequency(const double freq, const size_t chan);
-
- double set_tx_gain(const double gain, const size_t chan);
- double set_rx_gain(const double gain, const size_t chan);
- double set_rx_bandwidth(const double bandwidth, const size_t chan);
-
- double get_tx_gain(const size_t chan);
- double get_rx_gain(const size_t chan);
- double get_rx_bandwidth(const size_t chan);
-
- std::vector<std::string> get_gpio_banks() const;
- void set_gpio_attr(const std::string &bank, const std::string &attr, const uint32_t value, const uint32_t mask);
- uint32_t get_gpio_attr(const std::string &bank, const std::string &attr);
-
- size_t get_chan_from_dboard_fe(const std::string &fe, const direction_t);
- std::string get_dboard_fe_from_chan(const size_t chan, const direction_t);
-
- /************************************************************************
- * RFIC setup and control
- ***********************************************************************/
- /*! Set up the radio. No API calls may be made before this one.
- */
- void setup_radio(uhd::usrp::ad9361_ctrl::sptr safe_codec_ctrl);
-
-private:
- void _setup_radio_channel(const size_t chan);
- void _reset_radio(void);
-
-protected:
- /************************************************************************
- * Helpers
- ***********************************************************************/
- virtual bool check_radio_config();
- void _enforce_tick_rate_limits(const size_t chans, const double tick_rate);
-
-private:
- /************************************************************************
- * Peripheral controls
- ***********************************************************************/
- void _update_fe_lo_freq(const std::string &fe, const double freq);
- void _update_atrs(void);
- void _update_atr_leds(uhd::usrp::gpio_atr::gpio_atr_3000::sptr leds, const std::string &rx_ant);
-
- void _update_gpio_state(void);
- void _update_enables(void);
-
- void _update_time_source(const std::string &source);
-
- // get frontend lock sensor
- uhd::sensor_value_t _get_fe_pll_lock(const bool is_tx);
-
- /************************************************************************
- * Internal GPIO control
- ***********************************************************************/
- struct gpio_t
- {
- gpio_t() : pps_sel(uhd::usrp::e300::global_regs::PPS_INT),
- mimo(0), radio_rst(0), tx_bandsels(0),
- rx_bandsel_a(0), rx_bandsel_b(0), rx_bandsel_c(0)
- {}
-
- uint32_t pps_sel;
- uint32_t mimo;
- uint32_t radio_rst;
-
- uint32_t tx_bandsels;
- uint32_t rx_bandsel_a;
- uint32_t rx_bandsel_b;
- uint32_t rx_bandsel_c;
-
- static const size_t PPS_SEL = 0;
- static const size_t MIMO = 2;
- static const size_t RADIO_RST = 3;
- static const size_t TX_BANDSEL = 4;
- static const size_t RX_BANDSELA = 7;
- static const size_t RX_BANDSELB = 13;
- static const size_t RX_BANDSELC = 17;
- };
- uint8_t _get_internal_gpio(uhd::usrp::gpio_atr::gpio_atr_3000::sptr);
-
-private: // members
- struct e3xx_perifs_t
- {
- usrp::gpio_atr::gpio_atr_3000::sptr atr;
- uhd::usrp::gpio_atr::gpio_atr_3000::sptr leds;
- };
- //! SPI to talk to the AD936x
- spi_core_3000::sptr _spi;
- //! One ATR per channel
- std::map<size_t, e3xx_perifs_t> _e3xx_perifs;
- //! AD936x controls
- uhd::usrp::ad9361_ctrl::sptr _codec_ctrl;
- uhd::usrp::ad936x_manager::sptr _codec_mgr;
- gpio_t _misc;
-
-}; /* class radio_ctrl_impl */
-
-}} /* namespace uhd::rfnoc */
-
-#endif /* INCLUDED_LIBUHD_RFNOC_E3XX_RADIO_CTRL_IMPL_HPP */