aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2017-10-20 18:04:56 -0700
committerMartin Braun <martin.braun@ettus.com>2017-12-22 15:04:03 -0800
commitda3e5bcaaa420245b3ea1cd5c36f0c3d89f21d44 (patch)
tree2ea593fef47457ddb0130488ec29322d5568ca1e
parent54ec9dd8e90ed09a5e12bb9f2176942ac9e9238c (diff)
downloaduhd-da3e5bcaaa420245b3ea1cd5c36f0c3d89f21d44.tar.gz
uhd-da3e5bcaaa420245b3ea1cd5c36f0c3d89f21d44.tar.bz2
uhd-da3e5bcaaa420245b3ea1cd5c36f0c3d89f21d44.zip
mg: Add peripheral controls for CPLD and LO synthesizers
-rw-r--r--host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp91
-rw-r--r--host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp17
2 files changed, 106 insertions, 2 deletions
diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp
index 87a8d9439..54f2f64cc 100644
--- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp
+++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.cpp
@@ -5,13 +5,14 @@
//
#include "magnesium_radio_ctrl_impl.hpp"
-
+#include "spi_core_3000.hpp"
#include <uhd/utils/log.hpp>
#include <uhd/rfnoc/node_ctrl_base.hpp>
#include <uhd/transport/chdr.hpp>
#include <uhd/utils/math.hpp>
#include <uhd/types/direction.hpp>
#include <uhd/types/eeprom.hpp>
+#include <uhd/exception.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/make_shared.hpp>
#include <boost/format.hpp>
@@ -22,6 +23,12 @@ using namespace uhd::usrp;
using namespace uhd::rfnoc;
namespace {
+ enum slave_select_t {
+ SEN_CPLD = 1,
+ SEN_TX_LO = 2,
+ SEN_RX_LO = 4,
+ SEN_PHASE_DAC = 8
+ };
const double MAGNESIUM_TICK_RATE = 125e6; // Hz
const double MAGNESIUM_RADIO_RATE = 125e6; // Hz
@@ -45,7 +52,7 @@ namespace {
*
* These strings take the form of "RX1", "TX2", ...
*/
- std::string _get_which(direction_t dir, size_t chan)
+ std::string _get_which(const direction_t dir, const size_t chan)
{
UHD_ASSERT_THROW(dir == RX_DIRECTION or dir == TX_DIRECTION);
UHD_ASSERT_THROW(chan == 0 or chan == 1);
@@ -212,6 +219,86 @@ magnesium_radio_ctrl_impl::~magnesium_radio_ctrl_impl()
void magnesium_radio_ctrl_impl::_init_peripherals()
{
UHD_LOG_TRACE("MAGNESIUM", "Initializing peripherals...");
+ fs_path cpld_path = _root_path.branch_path()
+ / str(boost::format("Radio_%d") % ((get_block_id().get_block_count()/2)*2))
+ / "cpld";
+
+ // TODO: When we move back to 2 chans per RFNoC block, this needs to be
+ // non-conditional, and the else-branch goes away:
+ if (_radio_slot == "A" or _radio_slot == "C") {
+ UHD_LOG_TRACE("MAGNESIUM", "Initializing SPI core...");
+ _spi = spi_core_3000::make(_get_ctrl(0),
+ radio_ctrl_impl::regs::sr_addr(radio_ctrl_impl::regs::SPI),
+ radio_ctrl_impl::regs::RB_SPI);
+ } else {
+ UHD_LOG_TRACE("MAGNESIUM", "Not a master radio, no SPI core.");
+ }
+
+ UHD_LOG_TRACE("MAGNESIUM", "Initializing CPLD...");
+ UHD_LOG_TRACE("MAGNESIUM", "CPLD path: " << cpld_path);
+ if (not _tree->exists(cpld_path)) {
+ UHD_LOG_TRACE("MAGNESIUM", "Creating new CPLD object...");
+ spi_config_t spi_config;
+ spi_config.use_custom_divider = true;
+ spi_config.divider = 125;
+ spi_config.mosi_edge = spi_config_t::EDGE_RISE;
+ spi_config.miso_edge = spi_config_t::EDGE_FALL;
+ UHD_LOG_TRACE("MAGNESIUM", "Making CPLD object...");
+ _cpld = std::make_shared<magnesium_cpld_ctrl>(
+ [this, spi_config](const uint32_t transaction){ // Write functor
+ this->_spi->write_spi(
+ SEN_CPLD,
+ spi_config,
+ transaction,
+ 24
+ );
+ },
+ [this, spi_config](const uint32_t transaction){ // Read functor
+ return this->_spi->read_spi(
+ SEN_CPLD,
+ spi_config,
+ transaction,
+ 24
+ );
+ }
+ );
+ _tree->create<magnesium_cpld_ctrl::sptr>(cpld_path).set(_cpld);
+ } else {
+ UHD_LOG_TRACE("MAGNESIUM", "Reusing someone else's CPLD object...");
+ _cpld = _tree->access<magnesium_cpld_ctrl::sptr>(cpld_path).get();
+ }
+
+ // TODO: Same comment as above applies
+ if (_radio_slot == "A" or _radio_slot == "C") {
+ UHD_LOG_TRACE("MAGNESIUM", "Initializing TX LO...");
+ _tx_lo = adf435x_iface::make_adf4351(
+ [this](const std::vector<uint32_t> transactions){
+ for (const uint32_t transaction: transactions) {
+ this->_spi->write_spi(
+ SEN_TX_LO,
+ spi_config_t::EDGE_RISE,
+ transaction,
+ 32
+ );
+ }
+ }
+ );
+ UHD_LOG_TRACE("MAGNESIUM", "Initializing RX LO...");
+ _rx_lo = adf435x_iface::make_adf4351(
+ [this](const std::vector<uint32_t> transactions){
+ for (const uint32_t transaction: transactions) {
+ this->_spi->write_spi(
+ SEN_RX_LO,
+ spi_config_t::EDGE_RISE,
+ transaction,
+ 32
+ );
+ }
+ }
+ );
+ } else {
+ UHD_LOG_TRACE("MAGNESIUM", "Not a master radio, no LOs.");
+ }
}
void magnesium_radio_ctrl_impl::_init_defaults()
diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp
index 1a5caaeff..7c96e47d0 100644
--- a/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp
+++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_ctrl_impl.hpp
@@ -20,6 +20,10 @@
#include "radio_ctrl_impl.hpp"
#include "rpc_block_ctrl.hpp"
+#include "magnesium_cpld_ctrl.hpp"
+#include "magnesium_cpld_regs.hpp"
+#include "adf435x.hpp"
+#include <uhd/types/serial.hpp>
#include <uhd/usrp/dboard_manager.hpp>
#include <uhd/usrp/gpio_defs.hpp>
@@ -145,6 +149,19 @@ private:
//! Reference to the RPC client
uhd::rpc_client::sptr _rpcc;
+ //! Reference to the SPI core
+ uhd::spi_iface::sptr _spi;
+
+ //! Reference to the TX LO
+ adf435x_iface::sptr _tx_lo;
+
+ //! Reference to the RX LO
+ adf435x_iface::sptr _rx_lo;
+
+ //! Reference to the CPLD controls
+ std::shared_ptr<magnesium_cpld_ctrl> _cpld;
+
+
}; /* class radio_ctrl_impl */
}} /* namespace uhd::rfnoc */