From da3e5bcaaa420245b3ea1cd5c36f0c3d89f21d44 Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Fri, 20 Oct 2017 18:04:56 -0700 Subject: mg: Add peripheral controls for CPLD and LO synthesizers --- .../dboard/magnesium/magnesium_radio_ctrl_impl.cpp | 91 +++++++++++++++++++++- .../dboard/magnesium/magnesium_radio_ctrl_impl.hpp | 17 ++++ 2 files changed, 106 insertions(+), 2 deletions(-) (limited to 'host/lib/usrp/dboard/magnesium') 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 #include #include #include #include #include +#include #include #include #include @@ -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( + [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(cpld_path).set(_cpld); + } else { + UHD_LOG_TRACE("MAGNESIUM", "Reusing someone else's CPLD object..."); + _cpld = _tree->access(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 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 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 #include #include @@ -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 _cpld; + + }; /* class radio_ctrl_impl */ }} /* namespace uhd::rfnoc */ -- cgit v1.2.3