diff options
Diffstat (limited to 'mpm/lib/mykonos')
-rw-r--r-- | mpm/lib/mykonos/CMakeLists.txt | 1 | ||||
-rw-r--r-- | mpm/lib/mykonos/ad937x_ctrl.cpp | 30 | ||||
-rw-r--r-- | mpm/lib/mykonos/ad937x_device.cpp | 42 | ||||
-rw-r--r-- | mpm/lib/mykonos/ad937x_device.hpp | 9 | ||||
-rw-r--r-- | mpm/lib/mykonos/ad937x_spi_iface.cpp | 41 | ||||
-rw-r--r-- | mpm/lib/mykonos/adi_ctrl.cpp | 58 |
6 files changed, 107 insertions, 74 deletions
diff --git a/mpm/lib/mykonos/CMakeLists.txt b/mpm/lib/mykonos/CMakeLists.txt index f5e64064e..b79474cea 100644 --- a/mpm/lib/mykonos/CMakeLists.txt +++ b/mpm/lib/mykonos/CMakeLists.txt @@ -28,6 +28,7 @@ ENDMACRO(MYKONOS_APPEND_SOURCES) SET(mykonos_sources ${CMAKE_CURRENT_SOURCE_DIR}/ad937x_ctrl.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ad937x_device.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/ad937x_spi_iface.cpp ${CMAKE_CURRENT_SOURCE_DIR}/adi_ctrl.cpp ${UHD_HOST_ROOT}/lib/types/ranges.cpp ) diff --git a/mpm/lib/mykonos/ad937x_ctrl.cpp b/mpm/lib/mykonos/ad937x_ctrl.cpp index d6360dad6..69ffeb6c2 100644 --- a/mpm/lib/mykonos/ad937x_ctrl.cpp +++ b/mpm/lib/mykonos/ad937x_ctrl.cpp @@ -18,12 +18,15 @@ #include "ad937x_device.hpp" #include "adi/mykonos.h" #include "mpm/ad937x/ad937x_ctrl.hpp" +#include <mpm/exception.hpp> #include <sstream> #include <set> #include <functional> #include <iostream> +#include <algorithm> +using namespace mpm::chips; using namespace mpm::ad937x::device; static uhd::direction_t _get_direction_from_antenna(const std::string& antenna) @@ -36,7 +39,7 @@ static uhd::direction_t _get_direction_from_antenna(const std::string& antenna) return uhd::direction_t::TX_DIRECTION; } else { - throw uhd::runtime_error("ad937x_ctrl got an invalid channel string."); + throw mpm::runtime_error("ad937x_ctrl got an invalid channel string."); } return uhd::direction_t::RX_DIRECTION; } @@ -51,7 +54,7 @@ static chain_t _get_chain_from_antenna(const std::string& antenna) return chain_t::TWO; } else { - throw uhd::runtime_error("ad937x_ctrl got an invalid channel string."); + throw mpm::runtime_error("ad937x_ctrl got an invalid channel string."); } return chain_t::ONE; } @@ -66,7 +69,7 @@ std::set<size_t> _get_valid_fir_lengths(const std::string& which) case uhd::direction_t::TX_DIRECTION: return{ 16, 32, 48, 64, 80, 96 }; default: - UHD_THROW_INVALID_CODE_PATH(); + MPM_THROW_INVALID_CODE_PATH(); return std::set<size_t>(); } } @@ -111,7 +114,7 @@ uhd::meta_range_t ad937x_ctrl::get_gain_range(const std::string &which) case uhd::direction_t::TX_DIRECTION: return uhd::meta_range_t(ad937x_device::MIN_TX_GAIN, ad937x_device::MAX_TX_GAIN, ad937x_device::TX_GAIN_STEP); default: - UHD_THROW_INVALID_CODE_PATH(); + MPM_THROW_INVALID_CODE_PATH(); return uhd::meta_range_t(); } } @@ -121,7 +124,7 @@ class ad937x_ctrl_impl : public ad937x_ctrl public: ad937x_ctrl_impl( std::shared_ptr<std::mutex> spi_mutex, - uhd::spi_iface::sptr iface, + mpm::types::regs_iface::sptr iface, mpm::ad937x::gpio::gain_pins_t gain_pins) : spi_mutex(spi_mutex), device(iface.get(), gain_pins), @@ -251,7 +254,7 @@ public: auto dir = _get_direction_from_antenna(which); if (dir != uhd::direction_t::RX_DIRECTION) { - throw uhd::runtime_error("set_agc not valid for non-rx channels"); + throw mpm::runtime_error("set_agc not valid for non-rx channels"); } ad937x_device::gain_mode_t gain_mode; @@ -266,7 +269,7 @@ public: gain_mode = ad937x_device::gain_mode_t::HYBRID; } else { - throw uhd::runtime_error("invalid agc mode"); + throw mpm::runtime_error("invalid agc mode"); } std::lock_guard<std::mutex> lock(*spi_mutex); @@ -319,7 +322,7 @@ public: auto lengths = _get_valid_fir_lengths(which); if (std::find(lengths.begin(), lengths.end(), fir.size()) == lengths.end()) { - throw uhd::value_error("invalid filter length"); + throw mpm::value_error("invalid filter length"); } std::lock_guard<std::mutex> lock(*spi_mutex); @@ -370,7 +373,7 @@ public: // double comparison here should be okay because of clipping if (inc_step != dec_step) { - throw uhd::value_error("TX gain increment and decrement steps must be equal"); + throw mpm::value_error("TX gain increment and decrement steps must be equal"); } } @@ -381,11 +384,14 @@ public: private: ad937x_device device; std::shared_ptr<std::mutex> spi_mutex; - uhd::spi_iface::sptr _iface; + mpm::types::regs_iface::sptr _iface; }; -ad937x_ctrl::sptr ad937x_ctrl::make(std::shared_ptr<std::mutex> spi_mutex, uhd::spi_iface::sptr iface, mpm::ad937x::gpio::gain_pins_t gain_pins) -{ +ad937x_ctrl::sptr ad937x_ctrl::make( + std::shared_ptr<std::mutex> spi_mutex, + mpm::types::regs_iface::sptr iface, + mpm::ad937x::gpio::gain_pins_t gain_pins +) { return std::make_shared<ad937x_ctrl_impl>(spi_mutex, iface, gain_pins); } diff --git a/mpm/lib/mykonos/ad937x_device.cpp b/mpm/lib/mykonos/ad937x_device.cpp index 138e4e165..68065e67d 100644 --- a/mpm/lib/mykonos/ad937x_device.cpp +++ b/mpm/lib/mykonos/ad937x_device.cpp @@ -200,7 +200,7 @@ void ad937x_device::begin_initialization() uint8_t product_id = get_product_id(); if (product_id != AD9371_PRODUCT_ID) { - throw runtime_error(str( + throw mpm::runtime_error(str( boost::format("AD9371 product ID does not match expected ID! Read: %X Expected: %X") % int(product_id) % int(AD9371_PRODUCT_ID) )); @@ -208,7 +208,7 @@ void ad937x_device::begin_initialization() if (!get_pll_lock_status(pll_t::CLK_SYNTH)) { - throw runtime_error("AD937x CLK_SYNTH PLL failed to lock in initialize()"); + throw mpm::runtime_error("AD937x CLK_SYNTH PLL failed to lock in initialize()"); } uint8_t mcs_status = 0; @@ -223,7 +223,7 @@ void ad937x_device::finish_initialization() if ((mcs_status & 0x0A) != 0x0A) { - throw runtime_error("Multichip sync failed!"); + throw mpm::runtime_error("Multichip sync failed!"); } _call_api_function(std::bind(MYKONOS_initSubRegisterTables, mykonos_config.device)); @@ -289,18 +289,14 @@ void ad937x_device::enable_jesd_loopback(uint8_t enable) _call_api_function(std::bind(MYKONOS_setRxFramerDataSource, mykonos_config.device, enable)); } -ad937x_device::ad937x_device(spi_iface* iface, gain_pins_t gain_pins) : +ad937x_device::ad937x_device( + mpm::types::regs_iface* iface, + gain_pins_t gain_pins +) : full_spi_settings(iface), mykonos_config(&full_spi_settings.spi_settings), gain_ctrl(gain_pins) { - std::cout << "full spi settings addr " << &full_spi_settings << std::endl; - iface->read_spi(0, uhd::spi_config_t::EDGE_RISE, 400, 24); - std::cout << "adi spi settings addr " << &(full_spi_settings.spi_settings) << std::endl; - std::cout << "iface addr " << std::hex << iface << std::dec << std::endl; - - std::cout << "myk dev addr " << std::hex << mykonos_config.device->spiSettings << std::dec << std::endl; - } uint8_t ad937x_device::get_product_id() @@ -373,7 +369,7 @@ double ad937x_device::tune(direction_t direction, double value) mykonos_config.device->rx->rxPllLoFrequency_Hz = integer_value; break; default: - UHD_THROW_INVALID_CODE_PATH(); + MPM_THROW_INVALID_CODE_PATH(); } _call_api_function(std::bind(MYKONOS_setRfPllFrequency, mykonos_config.device, pll, integer_value)); @@ -393,7 +389,7 @@ double ad937x_device::get_freq(direction_t direction) case TX_DIRECTION: pll = TX_PLL; break; case RX_DIRECTION: pll = RX_PLL; break; default: - UHD_THROW_INVALID_CODE_PATH(); + MPM_THROW_INVALID_CODE_PATH(); } // TODO: coercion here causes extra device accesses, when the formula is provided on pg 119 of the user guide @@ -420,7 +416,7 @@ bool ad937x_device::get_pll_lock_status(pll_t pll) case pll_t::CALPLL_SDM: return (pll_status & 0x10) > 0; default: - UHD_THROW_INVALID_CODE_PATH(); + MPM_THROW_INVALID_CODE_PATH(); return false; } } @@ -470,7 +466,7 @@ double ad937x_device::set_gain(direction_t direction, chain_t chain, double valu func = MYKONOS_setTx2Attenuation; break; default: - UHD_THROW_INVALID_CODE_PATH(); + MPM_THROW_INVALID_CODE_PATH(); } _call_api_function(std::bind(func, mykonos_config.device, attenuation)); break; @@ -490,13 +486,13 @@ double ad937x_device::set_gain(direction_t direction, chain_t chain, double valu func = MYKONOS_setRx2ManualGain; break; default: - UHD_THROW_INVALID_CODE_PATH(); + MPM_THROW_INVALID_CODE_PATH(); } _call_api_function(std::bind(func, mykonos_config.device, gain)); break; } default: - UHD_THROW_INVALID_CODE_PATH(); + MPM_THROW_INVALID_CODE_PATH(); } return coerced_value; } @@ -518,10 +514,10 @@ void ad937x_device::set_agc_mode(direction_t direction, gain_mode_t mode) _call_api_function(std::bind(MYKONOS_setRxGainControlMode, mykonos_config.device, HYBRID)); break; default: - UHD_THROW_INVALID_CODE_PATH(); + MPM_THROW_INVALID_CODE_PATH(); } default: - UHD_THROW_INVALID_CODE_PATH(); + MPM_THROW_INVALID_CODE_PATH(); } } @@ -540,7 +536,7 @@ void ad937x_device::set_fir( mykonos_config.rx_fir_config.set_fir(gain, fir); break; default: - UHD_THROW_INVALID_CODE_PATH(); + MPM_THROW_INVALID_CODE_PATH(); } } @@ -556,7 +552,7 @@ std::vector<int16_t> ad937x_device::get_fir( case RX_DIRECTION: return mykonos_config.rx_fir_config.get_fir(gain); default: - UHD_THROW_INVALID_CODE_PATH(); + MPM_THROW_INVALID_CODE_PATH(); } } @@ -585,7 +581,7 @@ void ad937x_device::set_gain_pin_step_sizes(direction_t direction, chain_t chain gain_ctrl.config.at(direction).at(chain).dec_step = static_cast<uint8_t>(inc_step / 0.05); gain_ctrl.config.at(direction).at(chain).inc_step = static_cast<uint8_t>(dec_step / 0.05); } else { - UHD_THROW_INVALID_CODE_PATH(); + MPM_THROW_INVALID_CODE_PATH(); } _apply_gain_pins(direction, chain); } @@ -600,7 +596,7 @@ void ad937x_device::_apply_gain_pins(direction_t direction, chain_t chain) // TX direction does not support different steps per direction if (direction == TX_DIRECTION) { - UHD_ASSERT_THROW(chan.inc_step == chan.dec_step); + MPM_ASSERT_THROW(chan.inc_step == chan.dec_step); } switch (direction) diff --git a/mpm/lib/mykonos/ad937x_device.hpp b/mpm/lib/mykonos/ad937x_device.hpp index 729912adf..17a09f249 100644 --- a/mpm/lib/mykonos/ad937x_device.hpp +++ b/mpm/lib/mykonos/ad937x_device.hpp @@ -27,8 +27,8 @@ #include "adi/t_mykonos_gpio.h" #include "adi/mykonos_debug/t_mykonos_dbgjesd.h" -#include <uhd/exception.hpp> - +#include <mpm/spi/spi_iface.hpp> +#include <mpm/exception.hpp> #include <boost/noncopyable.hpp> #include <memory> #include <functional> @@ -39,7 +39,10 @@ public: enum class gain_mode_t { MANUAL, AUTOMATIC, HYBRID }; enum class pll_t {CLK_SYNTH, RX_SYNTH, TX_SYNTH, SNIFF_SYNTH, CALPLL_SDM}; - ad937x_device(uhd::spi_iface* iface, mpm::ad937x::gpio::gain_pins_t gain_pins); + ad937x_device( + mpm::types::regs_iface* iface, + mpm::ad937x::gpio::gain_pins_t gain_pins + ); void begin_initialization(); void finish_initialization(); diff --git a/mpm/lib/mykonos/ad937x_spi_iface.cpp b/mpm/lib/mykonos/ad937x_spi_iface.cpp new file mode 100644 index 000000000..66ea95d67 --- /dev/null +++ b/mpm/lib/mykonos/ad937x_spi_iface.cpp @@ -0,0 +1,41 @@ +// +// Copyright 2017 Ettus Research (National Instruments) +// +// 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 <mpm/ad937x/ad937x_spi_iface.hpp> +#include <mpm/spi/spi_regs_iface.hpp> + +using namespace mpm::spi; + +static const int MYK_SPI_SPEED_HZ = 1000000; +static const size_t MYK_ADDR_SHIFT = 8; +static const size_t MYK_DATA_SHIFT = 0; +static const size_t MYK_READ_FLAG = 1 << 23; +static const size_t MYK_WRITE_FLAG = 0; + +mpm::types::regs_iface::sptr mpm::chips::make_ad937x_iface( + const std::string &spi_device +) { + return make_spi_regs_iface( + spi_iface::make_spidev(spi_device, MYK_SPI_SPEED_HZ), + MYK_ADDR_SHIFT, + MYK_DATA_SHIFT, + MYK_READ_FLAG, + MYK_WRITE_FLAG + ); +} + + diff --git a/mpm/lib/mykonos/adi_ctrl.cpp b/mpm/lib/mykonos/adi_ctrl.cpp index 9a5f73607..be3fa0ddb 100644 --- a/mpm/lib/mykonos/adi_ctrl.cpp +++ b/mpm/lib/mykonos/adi_ctrl.cpp @@ -24,10 +24,10 @@ #include <chrono> #include <thread> -static const uint32_t MYKONOS_READ_BIT = (1 << 23); - -ad9371_spiSettings_t::ad9371_spiSettings_t(uhd::spi_iface* uhd_iface) : - spi_iface(uhd_iface) +ad9371_spiSettings_t::ad9371_spiSettings_t( + mpm::types::regs_iface* spi_iface_ +) : + spi_iface(spi_iface_) { spi_settings.chipSelectIndex = 0; // set later spi_settings.writeBitPolarity = 1; // unused @@ -41,11 +41,6 @@ ad9371_spiSettings_t::ad9371_spiSettings_t(uhd::spi_iface* uhd_iface) : spi_settings.spiClkFreq_Hz = 250000000; // currently unused } -uhd::spi_config_t::edge_t _get_edge(const spiSettings_t & sps) -{ - return (sps.CPOL ^ sps.CPHA) ? uhd::spi_config_t::EDGE_FALL : uhd::spi_config_t::EDGE_RISE; -} - // TODO: change // not implemented to meaningful errors // close hardware pointers @@ -90,14 +85,14 @@ commonErr_t CMB_setSPIChannel(uint16_t chipSelectIndex) // single SPI byte write function commonErr_t CMB_SPIWriteByte(spiSettings_t *spiSettings, uint16_t addr, uint8_t data) { - // TODO: crash and burn for these errors? - if (spiSettings == nullptr || spiSettings->MSBFirst == 0) return COMMONERR_FAILED; + if (spiSettings == nullptr || spiSettings->MSBFirst == 0) { + // TODO: crash and burn for these errors? + return COMMONERR_FAILED; + } - ad9371_spiSettings_t *mpm_spi = ad9371_spiSettings_t::make(spiSettings); - uhd::spi_config_t config(_get_edge(*spiSettings)); - uint32_t data_word = (0) | (addr << 8) | (data); + ad9371_spiSettings_t *spi = ad9371_spiSettings_t::make(spiSettings); try { - mpm_spi->spi_iface->write_spi(spiSettings->chipSelectIndex, config, data_word, 24); + spi->spi_iface->poke8(addr, data); return COMMONERR_OK; } catch (const std::exception &e) { std::cout << "AAAAAAAAAAAAH" << std::endl; @@ -107,22 +102,22 @@ commonErr_t CMB_SPIWriteByte(spiSettings_t *spiSettings, uint16_t addr, uint8_t commonErr_t CMB_SPIWriteBytes(spiSettings_t *spiSettings, uint16_t *addr, uint8_t *data, uint32_t count) { - // TODO: crash and burn for these errors? if (spiSettings == nullptr || addr == nullptr || data == nullptr || spiSettings->MSBFirst == 0) { + // TODO: crash and burn for these errors? return COMMONERR_FAILED; } - ad9371_spiSettings_t *mpm_spi = ad9371_spiSettings_t::make(spiSettings); - uhd::spi_config_t config(_get_edge(*spiSettings)); + ad9371_spiSettings_t *spi = ad9371_spiSettings_t::make(spiSettings); try { for (size_t i = 0; i < count; ++i) { uint32_t data_word = (0) | (addr[i] << 8) | (data[i]); - mpm_spi->spi_iface->write_spi(spiSettings->chipSelectIndex, config, data_word, 24); + + spi->spi_iface->poke8(addr[i], data[i]); } return COMMONERR_OK; } catch (const std::exception &e) { @@ -141,13 +136,9 @@ commonErr_t CMB_SPIReadByte (spiSettings_t *spiSettings, uint16_t addr, uint8_t return COMMONERR_FAILED; } - ad9371_spiSettings_t *mpm_spi = ad9371_spiSettings_t::make(spiSettings); - uhd::spi_config_t config(_get_edge(*spiSettings)); - uint32_t read_word = MYKONOS_READ_BIT | (addr << 8); - + ad9371_spiSettings_t *spi = ad9371_spiSettings_t::make(spiSettings); try { - *readdata = static_cast<uint8_t>( - mpm_spi->spi_iface->read_spi(spiSettings->chipSelectIndex, config, read_word, 24)); + *readdata = spi->spi_iface->peek8(addr); return COMMONERR_OK; } catch (const std::exception &e) { std::cout << "AAAAAAAAAAAAH READ" << std::endl; @@ -162,15 +153,12 @@ commonErr_t CMB_SPIWriteField( uint16_t addr, uint8_t field_val, uint8_t mask, uint8_t start_bit ) { - ad9371_spiSettings_t *mpm_spi = ad9371_spiSettings_t::make(spiSettings); - uhd::spi_config_t config(_get_edge(*spiSettings)); - uint32_t read_word = (0) | (addr << 8); + ad9371_spiSettings_t *spi = ad9371_spiSettings_t::make(spiSettings); try { - uint32_t current_value = mpm_spi->spi_iface->read_spi(spiSettings->chipSelectIndex, config, read_word, 24); - uint8_t new_value = static_cast<uint8_t>((current_value & ~mask) | (field_val << start_bit)); - uint32_t write_word = (0) | (addr << 8) | new_value; - mpm_spi->spi_iface->write_spi(spiSettings->chipSelectIndex, config, write_word, 24); + uint8_t current_value = spi->spi_iface->peek8(addr); + uint8_t new_value = ((current_value & ~mask) | (field_val << start_bit)); + spi->spi_iface->poke8(addr, new_value); return COMMONERR_OK; } catch (const std::exception &e) { std::cout << "AAAAAAAAAAAAH WRITE FIELD" << std::endl; @@ -186,12 +174,10 @@ commonErr_t CMB_SPIReadField( uint16_t addr, uint8_t *field_val, uint8_t mask, uint8_t start_bit ) { - ad9371_spiSettings_t *mpm_spi = ad9371_spiSettings_t::make(spiSettings); - uhd::spi_config_t config(_get_edge(*spiSettings)); - uint32_t read_word = MYKONOS_READ_BIT | (addr << 8); + ad9371_spiSettings_t *spi = ad9371_spiSettings_t::make(spiSettings); try { - uint32_t value = mpm_spi->spi_iface->read_spi(spiSettings->chipSelectIndex, config, read_word, 24); + uint8_t value = spi->spi_iface->peek8(addr); *field_val = static_cast<uint8_t>((value & mask) >> start_bit); return COMMONERR_OK; } catch (const std::exception &e) { |