diff options
Diffstat (limited to 'mpm')
25 files changed, 1234 insertions, 2699 deletions
| diff --git a/mpm/.gitignore b/mpm/.gitignore index 378eac25d..32f53b126 100644 --- a/mpm/.gitignore +++ b/mpm/.gitignore @@ -1 +1,2 @@  build +msvcbuild
\ No newline at end of file diff --git a/mpm/include/mpm/spi/adi_ctrl.hpp b/mpm/include/mpm/spi/adi_ctrl.hpp index d3269cecc..7cc87b586 100644 --- a/mpm/include/mpm/spi/adi_ctrl.hpp +++ b/mpm/include/mpm/spi/adi_ctrl.hpp @@ -17,15 +17,24 @@  #pragma once -#include <mpm/spi_iface.hpp> +// TODO: fix path of UHD include +#include <../../host/include/uhd/types/serial.hpp> -struct mpm_spiSettings_t +#include <chrono> + +struct ad9371_spiSettings_t  { -    static mpm_spiSettings_t* make(spiSettings_t *sps) { -        return reinterpret_cast<mpm_spiSettings_t *>(sps); +    static ad9371_spiSettings_t* make(spiSettings_t *sps) { +        return reinterpret_cast<ad9371_spiSettings_t *>(sps);      } +    explicit ad9371_spiSettings_t(uhd::spi_iface::sptr uhd_iface); + +    // spiSetting_t MUST be the first data member so that the +    // reintrepret_cast in make() works      spiSettings_t spi_settings; -    mpm::spi_iface *spi_iface; +    uhd::spi_iface::sptr spi_iface; +    std::chrono::time_point<std::chrono::steady_clock> timeout_start; +    std::chrono::microseconds timeout_duration;  }; diff --git a/mpm/lib/mykonos/CMakeLists.txt b/mpm/lib/mykonos/CMakeLists.txt index 03b3ef102..182058405 100644 --- a/mpm/lib/mykonos/CMakeLists.txt +++ b/mpm/lib/mykonos/CMakeLists.txt @@ -32,7 +32,6 @@ SET(mykonos_sources  )  ADD_SUBDIRECTORY(adi) -ADD_SUBDIRECTORY(adi_sample)  ADD_SUBDIRECTORY(config)  USRP_PERIPHS_ADD_OBJECT(mykonos ${mykonos_sources}) diff --git a/mpm/lib/mykonos/ad937x_ctrl.cpp b/mpm/lib/mykonos/ad937x_ctrl.cpp index b4ff38139..a5cd842f5 100644 --- a/mpm/lib/mykonos/ad937x_ctrl.cpp +++ b/mpm/lib/mykonos/ad937x_ctrl.cpp @@ -1,15 +1,31 @@ -#include "adi/mykonos.h" +// +// 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 "ad937x_ctrl.hpp"  #include "ad937x_device.hpp" +#include "ad937x_ctrl.hpp" +#include "adi/mykonos.h" +  #include <sstream> +#include <set>  #include <functional> -#include <iostream> -#include <cmath>  uhd::meta_range_t ad937x_ctrl::get_rf_freq_range(void)  { -    return uhd::meta_range_t(300e6, 6e9); +    return uhd::meta_range_t(ad937x_device::MIN_FREQ, ad937x_device::MAX_FREQ);  }  uhd::meta_range_t ad937x_ctrl::get_bw_filter_range(void)  @@ -18,7 +34,7 @@ uhd::meta_range_t ad937x_ctrl::get_bw_filter_range(void)      return uhd::meta_range_t(0, 1);  } -std::vector<double> ad937x_ctrl::get_clock_rates(void) +std::set<double> ad937x_ctrl::get_clock_rates(void)  {      // TODO: fix      return { 125e6 }; @@ -30,16 +46,16 @@ uhd::meta_range_t ad937x_ctrl::get_gain_range(const std::string &which)      switch (dir)      {      case uhd::direction_t::RX_DIRECTION: -        return uhd::meta_range_t(0, 30, 0.5); +        return uhd::meta_range_t(ad937x_device::MIN_RX_GAIN, ad937x_device::MAX_RX_GAIN, ad937x_device::RX_GAIN_STEP);      case uhd::direction_t::TX_DIRECTION: -        return uhd::meta_range_t(0, 41.95, 0.05); +        return uhd::meta_range_t(ad937x_device::MIN_TX_GAIN, ad937x_device::MAX_TX_GAIN, ad937x_device::TX_GAIN_STEP);      default: -        throw uhd::runtime_error("ad937x_ctrl got an invalid channel string."); +        UHD_THROW_INVALID_CODE_PATH();          return uhd::meta_range_t();      }  } -std::vector<size_t> ad937x_ctrl::_get_valid_fir_lengths(const std::string& which) +std::set<size_t> ad937x_ctrl::_get_valid_fir_lengths(const std::string& which)  {      auto dir = _get_direction_from_antenna(which);      switch (dir) @@ -49,8 +65,8 @@ std::vector<size_t> ad937x_ctrl::_get_valid_fir_lengths(const std::string& which      case uhd::direction_t::TX_DIRECTION:          return { 16, 32, 48, 64, 80, 96 };      default: -        throw uhd::runtime_error("ad937x_ctrl got an invalid channel string."); -        return std::vector<size_t>(); +        UHD_THROW_INVALID_CODE_PATH(); +        return std::set<size_t>();      }  } @@ -87,30 +103,27 @@ ad937x_device::chain_t ad937x_ctrl::_get_chain_from_antenna(const std::string& a  class ad937x_ctrl_impl : public ad937x_ctrl  {  public: -    // change to uhd::spi_iface -    static sptr make(spi_lock::sptr spi_l, mpm::spi_iface::sptr iface); - -    ad937x_ctrl_impl(spi_lock::sptr spi_l, mpm::spi_iface::sptr iface) : +    ad937x_ctrl_impl(spi_lock::sptr spi_l, uhd::spi_iface::sptr iface) :          spi_l(spi_l), -        iface(iface) +        device(iface)      {      }      virtual uint8_t get_product_id()      { -        std::lock_guard<spi_lock>(*spi_l); +        std::lock_guard<spi_lock> lock(*spi_l);          return device.get_product_id();      }      virtual uint8_t get_device_rev()      { -        std::lock_guard<spi_lock>(*spi_l); +        std::lock_guard<spi_lock> lock(*spi_l);          return device.get_device_rev();      }      virtual std::string get_api_version()      { -        std::lock_guard<spi_lock>(*spi_l); +        std::lock_guard<spi_lock> lock(*spi_l);          auto api = device.get_api_version();          std::ostringstream ss;          ss  << api.silicon_ver << "." @@ -122,7 +135,7 @@ public:      virtual std::string get_arm_version()      { -        std::lock_guard<spi_lock>(*spi_l); +        std::lock_guard<spi_lock> lock(*spi_l);          auto arm = device.get_arm_version();          std::ostringstream ss;          ss  << arm.major_ver << "." @@ -131,27 +144,19 @@ public:          return ss.str();      } -    virtual double set_bw_filter(const std::string &which, const double value) +    virtual double set_bw_filter(const std::string &which, double value)      {          // TODO implement          return double();      } -    virtual double set_gain(const std::string &which, const double value) +    virtual double set_gain(const std::string &which, double value)      {          auto dir = _get_direction_from_antenna(which);          auto chain = _get_chain_from_antenna(which); -        return device.set_gain(dir, chain, value); -    } -    virtual void set_agc(const std::string &which, const bool enable) -    { -        auto dir = _get_direction_from_antenna(which); -        if (dir != uhd::direction_t::RX_DIRECTION) -        { -            throw uhd::runtime_error("ad937x_ctrl::set_agc was called on a non-RX channel"); -        } -        return device.set_agc(dir, enable); +        std::lock_guard<spi_lock> lock(*spi_l); +        return device.set_gain(dir, chain, value);      }      virtual void set_agc_mode(const std::string &which, const std::string &mode) @@ -159,7 +164,7 @@ public:          auto dir = _get_direction_from_antenna(which);          if (dir != uhd::direction_t::RX_DIRECTION)          { -            throw uhd::runtime_error("ad937x_ctrl::set_agc was called on a non-RX channel"); +            throw uhd::runtime_error("set_agc not valid for non-rx channels");          }          ad937x_device::gain_mode_t gain_mode; @@ -174,392 +179,89 @@ public:              gain_mode = ad937x_device::gain_mode_t::HYBRID;          }          else { -            throw uhd::runtime_error("ad937x_ctrl::set_agc_mode was called on a non-RX channel"); +            throw uhd::runtime_error("invalid agc mode");          } +        std::lock_guard<spi_lock> lock(*spi_l);          device.set_agc_mode(dir, gain_mode);      } -    virtual double set_clock_rate(const double value) +    virtual double set_clock_rate(double value)      {          auto rates = get_clock_rates(); -        auto coerced_value = value; -        if (std::find(rates.begin(), rates.end(), value) == rates.end()) +        if (std::find(rates.cbegin(), rates.cend(), value) == rates.end())          { -            coerced_value = rates[0]; +            value = *(rates.cbegin());          } -        return device.set_clock_rate(coerced_value); +        std::lock_guard<spi_lock> lock(*spi_l); +        return device.set_clock_rate(value);      } -    virtual void enable_channel(const std::string &which, const bool enable) +    virtual void enable_channel(const std::string &which, bool enable)      {          auto dir = _get_direction_from_antenna(which);          auto chain = _get_chain_from_antenna(which); + +        std::lock_guard<spi_lock> lock(*spi_l);          return device.enable_channel(dir, chain, enable);      } -    virtual double set_freq(const std::string &which, const double value) +    virtual double set_freq(const std::string &which, double value)      {          auto dir = _get_direction_from_antenna(which);          auto clipped_value = get_rf_freq_range().clip(value); + +        std::lock_guard<spi_lock> lock(*spi_l);          return device.tune(dir, clipped_value);      }      virtual double get_freq(const std::string &which)      {          auto dir = _get_direction_from_antenna(which); + +        std::lock_guard<spi_lock> lock(*spi_l);          return device.get_freq(dir);      }      virtual void set_fir(const std::string &which, int8_t gain, const std::vector<int16_t> & fir)      { +        auto dir = _get_direction_from_antenna(which); +        auto chain = _get_chain_from_antenna(which); +          auto lengths = _get_valid_fir_lengths(which);          if (std::find(lengths.begin(), lengths.end(), fir.size()) == lengths.end())          { -            throw uhd::value_error("ad937x_ctrl::set_fir got filter of invalid length"); +            throw uhd::value_error("invalid filter length");          } -        ad937x_fir(gain, fir); - -    } -    virtual std::vector<int16_t> get_fir(const std::string &which) = 0; - -    virtual int16_t get_temperature() = 0; -     -private: -    ad937x_device device; -    spi_lock::sptr spi_l; -    mpm::spi_iface::sptr iface; -}; - -const double ad937x_ctrl_impl::MIN_FREQ = 300e6; -const double ad937x_ctrl_impl::MAX_FREQ = 6e9; - -/* -ad937x_ctrl::sptr ad937x_ctrl_impl::make( -    spi_lock::sptr spi_l, -    mpm::spi_iface::sptr iface) -{ -    return std::make_shared<ad937x_ctrl_impl>(spi_l, iface); -} - - -void ad937x_ctrl::initialize() -{ -    //headlessinit(mykonos_config.device); -    // TODO: finish initialization -    { -        std::lock_guard<spi_lock> lock(*spi_l); -        call_api_function(std::bind(MYKONOS_initialize, mykonos_config.device)); -    }     -    get_product_id(); -} - -ad937x_ctrl::ad937x_ctrl( -    spi_lock::sptr spi_l,  -    mpm::spi_iface::sptr iface) : -    spi_l(spi_l), -    iface(iface) -{ -    mpm_sps.spi_iface = iface.get(); - -    //TODO assert iface->get_chip_select() is 1-8 -    mpm_sps.spi_settings.chipSelectIndex = static_cast<uint8_t>(iface->get_chip_select()); -    mpm_sps.spi_settings.writeBitPolarity = 1; -    mpm_sps.spi_settings.longInstructionWord = 1; // set to 1 by initialize -    mpm_sps.spi_settings.MSBFirst =  -        (iface->get_endianness() == mpm::spi_iface::spi_endianness_t::LSB_FIRST) ? 0 : 1; -    mpm_sps.spi_settings.CPHA = 0; // set to 0 by initialize -    mpm_sps.spi_settings.CPOL = 0; // set to 0 by initialize -    mpm_sps.spi_settings.enSpiStreaming = 1; -    mpm_sps.spi_settings.autoIncAddrUp = 1; -    mpm_sps.spi_settings.fourWireMode =  -        (iface->get_wire_mode() == mpm::spi_iface::spi_wire_mode_t::THREE_WIRE_MODE) ? 0 : 1; -    mpm_sps.spi_settings.spiClkFreq_Hz = 25000000;  - -    initialize(); -} - -// helper function to unify error handling -// bind is bad, but maybe this is justifiable -void ad937x_ctrl::call_api_function(std::function<mykonosErr_t()> func) -{ -    auto error = func(); -    if (error != MYKONOS_ERR_OK) -    { -        std::cout << getMykonosErrorMessage(error); -        // TODO: make UHD exception -        //throw std::exception(getMykonosErrorMessage(error)); -    } -} - -uint8_t ad937x_ctrl::get_product_id() -{ -    std::lock_guard<spi_lock> lock(*spi_l); -    uint8_t id; -    call_api_function(std::bind(MYKONOS_getProductId, mykonos_config.device, &id)); -    return id; -} - -double ad937x_ctrl::set_clock_rate(const double req_rate) -{ -    auto rate = static_cast<decltype(mykonos_config.device->clocks->deviceClock_kHz)>(req_rate / 1000); -    mykonos_config.device->clocks->deviceClock_kHz = rate; -    { -        std::lock_guard<spi_lock> lock(*spi_l); -        call_api_function(std::bind(MYKONOS_initDigitalClocks, mykonos_config.device)); -    } -    return static_cast<decltype(set_clock_rate(0))>(rate); -} - -void ad937x_ctrl::_set_active_tx_chains(bool tx1, bool tx2) -{ -    decltype(mykonos_config.device->tx->txChannels) newTxChannel; -    if (tx1 && tx2) -    { -        newTxChannel = TX1_TX2; -    } -    else if (tx1) { -        newTxChannel = TX1; -    } -    else if (tx2) { -        newTxChannel = TX2; -    } -    else { -        newTxChannel = TXOFF; -    } -    mykonos_config.device->tx->txChannels = newTxChannel; -} - -void ad937x_ctrl::_set_active_rx_chains(bool rx1, bool rx2) -{ -    decltype(mykonos_config.device->rx->rxChannels) newRxChannel; -    if (rx1 && rx2) -    { -        newRxChannel = RX1_RX2; -    } -    else if (rx1) { -        newRxChannel = RX1; -    } -    else if (rx2) { -        newRxChannel = RX2; -    } -    else { -        newRxChannel = RXOFF; -    } -    mykonos_config.device->rx->rxChannels = newRxChannel; -} - -void ad937x_ctrl::set_active_chains(direction_t direction, bool channel1, bool channel2) -{ -    switch (direction) -    { -    case TX: _set_active_tx_chains(channel1, channel2); break; -    case RX: _set_active_rx_chains(channel1, channel2); break; -    default: -        // TODO: bad code path exception -        throw std::exception(); -    } -    // TODO: make this apply the setting -} - -double ad937x_ctrl::tune(direction_t direction, const double value) -{ -    // I'm not really sure why we set the PLL value in the config AND as a function parameter -    // but here it is - -    mykonosRfPllName_t pll; -    uint64_t integer_value = static_cast<uint64_t>(value); -    switch (direction) -    { -    case TX: -        pll = TX_PLL; -        mykonos_config.device->tx->txPllLoFrequency_Hz = integer_value; -        break; -    case RX: -        pll = RX_PLL; -        mykonos_config.device->rx->rxPllLoFrequency_Hz = integer_value; -        break; -    default: -        // TODO: bad code path exception -        throw std::exception(); -    } - -    { -        std::lock_guard<spi_lock> lock(*spi_l); -        call_api_function(std::bind(MYKONOS_setRfPllFrequency, mykonos_config.device, pll, integer_value)); -    } - -    // TODO: coercion here causes extra device accesses, when the formula is provided on pg 119 of the user guide -    // Furthermore, because coerced is returned as an integer, it's not even accurate -    uint64_t coerced_pll; -    {          std::lock_guard<spi_lock> lock(*spi_l); -        call_api_function(std::bind(MYKONOS_getRfPllFrequency, mykonos_config.device, pll, &coerced_pll)); +        device.set_fir(dir, chain, gain, fir);      } -    return static_cast<double>(coerced_pll); -} -double ad937x_ctrl::get_freq(direction_t direction) -{ -    mykonosRfPllName_t pll; -    switch (direction) +    std::vector<int16_t> get_fir(const std::string &which, int8_t &gain)      { -    case TX: pll = TX_PLL; break; -    case RX: pll = RX_PLL; break; -    default: -        // TODO: bad code path exception -        throw std::exception(); -    } +        auto dir = _get_direction_from_antenna(which); +        auto chain = _get_chain_from_antenna(which); -    // TODO: coercion here causes extra device accesses, when the formula is provided on pg 119 of the user guide -    // Furthermore, because coerced is returned as an integer, it's not even accurate -    uint64_t coerced_pll; -    {          std::lock_guard<spi_lock> lock(*spi_l); -        call_api_function(std::bind(MYKONOS_getRfPllFrequency, mykonos_config.device, pll, &coerced_pll)); +        return device.get_fir(dir, chain, gain);      } -    return static_cast<double>(coerced_pll); -    return double(); -} - -// RX Gain values are table entries given in mykonos_user.h -// An array of gain values is programmed at initialization, which the API will then use for its gain values -// In general, Gain Value = (255 - Gain Table Index) -uint8_t ad937x_ctrl::_convert_rx_gain(double inGain, double &coercedGain) -{ -    // TODO: use uhd::meta_range? -    const static double min_gain = 0; -    const static double max_gain = 30; -    const static double gain_step = 0.5; -    coercedGain = inGain; -    if (coercedGain < min_gain) +    virtual int16_t get_temperature()      { -        coercedGain = min_gain; -    } -    if (coercedGain > max_gain) -    { -        coercedGain = max_gain; -    } - -    // round to nearest step -    coercedGain = std::round(coercedGain * (1.0 / gain_step)) / (1.0 / gain_step); - -    // gain should be a value 0-60, add 195 to make 195-255 -    return static_cast<uint8_t>((coercedGain * 2) + 195); -} - -// TX gain is completely different from RX gain for no good reason so deal with it -// TX is set as attenuation using a value from 0-41950 mdB -// Only increments of 50 mdB are valid -uint16_t ad937x_ctrl::_convert_tx_gain(double inGain, double &coercedGain) -{ -    // TODO: use uhd::meta_range? -    const static double min_gain = 0; -    const static double max_gain = 41.95; -    const static double gain_step = 0.05; - -    coercedGain = inGain; -    if (coercedGain < min_gain) -    { -        coercedGain = min_gain; -    } -    if (coercedGain > max_gain) -    { -        coercedGain = max_gain; -    } - -    coercedGain = std::round(coercedGain * (1.0 / gain_step)) / (1.0 / gain_step); - -    // attenuation is inverted and in mdB not dB -    return static_cast<uint16_t>((max_gain - (coercedGain)) * 1000); -} - - -double ad937x_ctrl::set_gain(direction_t direction, chain_t chain, const double value) -{ -    double coerced_value; -    switch (direction) -    { -    case TX: -    { -        uint16_t attenuation = _convert_tx_gain(value, coerced_value); -        std::function<mykonosErr_t(mykonosDevice_t*, uint16_t)> func; -        switch (chain) -        { -        case CHAIN_1: -            func = MYKONOS_setTx1Attenuation; -            break; -        case CHAIN_2: -            func = MYKONOS_setTx2Attenuation; -            break; -        default: -            // TODO: bad code path exception -            throw std::exception(); -        }          std::lock_guard<spi_lock> lock(*spi_l); -        call_api_function(std::bind(func, mykonos_config.device, attenuation)); -        break; +        return device.get_temperature();      } -    case RX: -    { -        uint8_t gain = _convert_rx_gain(value, coerced_value); -        std::function<mykonosErr_t(mykonosDevice_t*, uint8_t)> func; -        switch (chain) -        { -        case CHAIN_1: -            func = MYKONOS_setRx1ManualGain; -            break; -        case CHAIN_2: -            func = MYKONOS_setRx2ManualGain; -            break; -        default: -            // TODO: bad code path exception -            throw std::exception(); -        } -        std::lock_guard<spi_lock> lock(*spi_l); -        call_api_function(std::bind(func, mykonos_config.device, gain)); -        break; -    } -    default: -        // TODO: bad code path exception -        throw std::exception(); -    } -    return coerced_value; -} +     +private: +    ad937x_device device; +    spi_lock::sptr spi_l; +}; -double ad937x_ctrl::set_agc_mode(direction_t direction, chain_t chain, gain_mode_t mode) +ad937x_ctrl::sptr ad937x_ctrl::make(spi_lock::sptr spi_l, uhd::spi_iface::sptr iface)  { -    std::lock_guard<spi_lock> lock(*spi_l); -    switch (direction) -    { -    case RX: -        switch (mode) -        { -        case GAIN_MODE_MANUAL: -            call_api_function(std::bind(MYKONOS_resetRxAgc, mykonos_config.device)); -            break; -        case GAIN_MODE_SLOW_AGC: -        case GAIN_MODE_FAST_AGC: -            // TODO: differentiate these -            call_api_function(std::bind(MYKONOS_setupRxAgc, mykonos_config.device)); -            break; -        default: -            // TODO: bad code path exception -            throw std::exception(); -        } -    default: -        // TODO: bad code path exception -        throw std::exception(); -    } -    return double(); +    return std::make_shared<ad937x_ctrl_impl>(spi_l, iface);  } -ad937x_ctrl::sptr ad937x_ctrl::make(spi_lock::sptr spi_l, mpm::spi_iface::sptr iface) -{ -    return std::make_shared<ad937x_ctrl>(spi_l, iface); -} -*/ diff --git a/mpm/lib/mykonos/ad937x_ctrl.hpp b/mpm/lib/mykonos/ad937x_ctrl.hpp index 6d36bdf05..213a146b4 100644 --- a/mpm/lib/mykonos/ad937x_ctrl.hpp +++ b/mpm/lib/mykonos/ad937x_ctrl.hpp @@ -1,41 +1,46 @@ +// +// 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/>. +// +  #pragma once +#include "ad937x_device.hpp" +#include "../spi/spi_lock.h" +  // TODO: fix path of UHD includes  #include <../../host/include/uhd/types/direction.hpp>  #include <../../host/include/uhd/types/ranges.hpp>  #include <../../host/include/uhd/exception.hpp> +#include <../../host/include/uhd/types/serial.hpp> -#include "config/ad937x_fir.h" -#include "adi/t_mykonos.h" -#include "../spi/spi_lock.h" -#include "../spi/spi_config.h" -#include <mpm/spi_iface.hpp> -#include <mpm/spi/adi_ctrl.hpp>  #include <boost/noncopyable.hpp> +#include <memory>  #include <functional> - -struct ad937x_api_version_t { -    uint32_t silicon_ver; -    uint32_t major_ver; -    uint32_t minor_ver; -    uint32_t build_ver; -}; - -struct ad937x_arm_version_t { -    uint32_t major_ver; -    uint32_t minor_ver; -    uint32_t rc_ver; -}; +#include <set>  class ad937x_ctrl : public boost::noncopyable  {  public:      typedef std::shared_ptr<ad937x_ctrl> sptr; +    static sptr make(spi_lock::sptr spi_l, uhd::spi_iface::sptr iface);      virtual ~ad937x_ctrl(void) {};      static uhd::meta_range_t get_rf_freq_range(void);      static uhd::meta_range_t get_bw_filter_range(void); -    static std::vector<double> get_clock_rates(void); +    static std::set<double> get_clock_rates(void);      static uhd::meta_range_t get_gain_range(const std::string &which);      virtual uint8_t get_product_id() = 0; @@ -43,20 +48,19 @@ public:      virtual std::string get_api_version() = 0;      virtual std::string get_arm_version() = 0; -    virtual double set_bw_filter(const std::string &which, const double value) = 0; -    virtual double set_gain(const std::string &which, const double value) = 0; +    virtual double set_bw_filter(const std::string &which, double value) = 0; +    virtual double set_gain(const std::string &which, double value) = 0; -    virtual void set_agc(const std::string &which, const bool enable) = 0;      virtual void set_agc_mode(const std::string &which, const std::string &mode) = 0; -    virtual double set_clock_rate(const double value) = 0; -    virtual void enable_channel(const std::string &which, const bool enable) = 0; +    virtual double set_clock_rate(double value) = 0; +    virtual void enable_channel(const std::string &which, bool enable) = 0; -    virtual double set_freq(const std::string &which, const double value) = 0; +    virtual double set_freq(const std::string &which, double value) = 0;      virtual double get_freq(const std::string &which) = 0; -    virtual void set_fir(const std::string &which, const std::vector<int16_t> & fir) = 0; -    virtual std::vector<int16_t> get_fir(const std::string &which) = 0; +    virtual void set_fir(const std::string &which, int8_t gain, const std::vector<int16_t> & fir) = 0; +    virtual std::vector<int16_t> get_fir(const std::string &which, int8_t &gain) = 0;      virtual int16_t get_temperature() = 0; @@ -64,5 +68,5 @@ protected:      static uhd::direction_t _get_direction_from_antenna(const std::string& antenna);      static ad937x_device::chain_t _get_chain_from_antenna(const std::string& antenna); -    static std::vector<size_t> _get_valid_fir_lengths(const std::string& which); +    static std::set<size_t> _get_valid_fir_lengths(const std::string& which);  };
\ No newline at end of file diff --git a/mpm/lib/mykonos/ad937x_device.cpp b/mpm/lib/mykonos/ad937x_device.cpp index 305ef2965..62725f219 100644 --- a/mpm/lib/mykonos/ad937x_device.cpp +++ b/mpm/lib/mykonos/ad937x_device.cpp @@ -1,58 +1,90 @@ -#include "adi/mykonos.h" +// +// 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 "ad937x_device.hpp" +#include "adi/mykonos.h" +#include "adi/mykonos_gpio.h" +  #include <functional>  #include <iostream> -#include <cmath> - -/* -ad937x_ctrl::sptr ad937x_ctrl_impl::make( -    spi_lock::sptr spi_l, -    mpm::spi_iface::sptr iface) -{ -    return std::make_shared<ad937x_ctrl_impl>(spi_l, iface); -} - - -void ad937x_ctrl::initialize() -{ -    //headlessinit(mykonos_config.device); -    // TODO: finish initialization -    { -        std::lock_guard<spi_lock> lock(*spi_l); -        call_api_function(std::bind(MYKONOS_initialize, mykonos_config.device)); -    }     -    get_product_id(); -} -ad937x_ctrl::ad937x_ctrl( -    spi_lock::sptr spi_l,  -    mpm::spi_iface::sptr iface) : -    spi_l(spi_l), -    iface(iface) -{ -    mpm_sps.spi_iface = iface.get(); - -    //TODO assert iface->get_chip_select() is 1-8 -    mpm_sps.spi_settings.chipSelectIndex = static_cast<uint8_t>(iface->get_chip_select()); -    mpm_sps.spi_settings.writeBitPolarity = 1; -    mpm_sps.spi_settings.longInstructionWord = 1; // set to 1 by initialize -    mpm_sps.spi_settings.MSBFirst =  -        (iface->get_endianness() == mpm::spi_iface::spi_endianness_t::LSB_FIRST) ? 0 : 1; -    mpm_sps.spi_settings.CPHA = 0; // set to 0 by initialize -    mpm_sps.spi_settings.CPOL = 0; // set to 0 by initialize -    mpm_sps.spi_settings.enSpiStreaming = 1; -    mpm_sps.spi_settings.autoIncAddrUp = 1; -    mpm_sps.spi_settings.fourWireMode =  -        (iface->get_wire_mode() == mpm::spi_iface::spi_wire_mode_t::THREE_WIRE_MODE) ? 0 : 1; -    mpm_sps.spi_settings.spiClkFreq_Hz = 25000000;  - -    initialize(); -} +const double ad937x_device::MIN_FREQ = 300e6; +const double ad937x_device::MAX_FREQ = 6e9; +const double ad937x_device::MIN_RX_GAIN = 0.0; +const double ad937x_device::MAX_RX_GAIN = 30.0; +const double ad937x_device::RX_GAIN_STEP = 0.5; +const double ad937x_device::MIN_TX_GAIN = 0.0; +const double ad937x_device::MAX_TX_GAIN = 41.95; +const double ad937x_device::TX_GAIN_STEP = 0.05; + +static const double RX_DEFAULT_FREQ = 1e9; +static const double TX_DEFAULT_FREQ = 1e9; + +// TODO: get the actual device ID +static const uint32_t AD9371_PRODUCT_ID = 0x1F; + +// TODO: move this to whereever we declare the ARM binary +static const size_t ARM_BINARY_SIZE = 98304; + +static const uint32_t INIT_CAL_TIMEOUT_MS = 10000; + +static const uint32_t INIT_CALS = +    TX_BB_FILTER |  +    ADC_TUNER |  +    TIA_3DB_CORNER |  +    DC_OFFSET | +    TX_ATTENUATION_DELAY |  +    RX_GAIN_DELAY |  +    FLASH_CAL | +    PATH_DELAY |  +    TX_LO_LEAKAGE_INTERNAL |  +//  TX_LO_LEAKAGE_EXTERNAL | +    TX_QEC_INIT | +    LOOPBACK_RX_LO_DELAY |  +    LOOPBACK_RX_RX_QEC_INIT | +    RX_LO_DELAY |  +    RX_QEC_INIT | +//  DPD_INIT | +//  CLGC_INIT | +//  VSWR_INIT | +    0; + +static const uint32_t TRACKING_CALS = +    TRACK_RX1_QEC | +    TRACK_RX2_QEC | +    TRACK_ORX1_QEC | +    TRACK_ORX2_QEC | +//  TRACK_TX1_LOL | +//  TRACK_TX2_LOL | +    TRACK_TX1_QEC | +    TRACK_TX2_QEC | +//  TRACK_TX1_DPD | +//  TRACK_TX2_DPD | +//  TRACK_TX1_CLGC | +//  TRACK_TX2_CLGC | +//  TRACK_TX1_VSWR | +//  TRACK_TX2_VSWR | +//  TRACK_ORX1_QEC_SNLO | +//  TRACK_ORX2_QEC_SNLO | +//  TRACK_SRX_QEC | +    0;  // helper function to unify error handling -// bind is bad, but maybe this is justifiable -void ad937x_ctrl::call_api_function(std::function<mykonosErr_t()> func) +void ad937x_device::_call_api_function(std::function<mykonosErr_t()> func)  {      auto error = func();      if (error != MYKONOS_ERR_OK) @@ -63,272 +95,422 @@ void ad937x_ctrl::call_api_function(std::function<mykonosErr_t()> func)      }  } -uint8_t ad937x_ctrl::get_product_id() +// helper function to unify error handling, GPIO version +void ad937x_device::_call_gpio_api_function(std::function<mykonosGpioErr_t()> func)  { -    std::lock_guard<spi_lock> lock(*spi_l); -    uint8_t id; -    call_api_function(std::bind(MYKONOS_getProductId, mykonos_config.device, &id)); -    return id; -} - -double ad937x_ctrl::set_clock_rate(const double req_rate) -{ -    auto rate = static_cast<decltype(mykonos_config.device->clocks->deviceClock_kHz)>(req_rate / 1000); -    mykonos_config.device->clocks->deviceClock_kHz = rate; +    auto error = func(); +    if (error != MYKONOS_ERR_GPIO_OK)      { -        std::lock_guard<spi_lock> lock(*spi_l); -        call_api_function(std::bind(MYKONOS_initDigitalClocks, mykonos_config.device)); +        std::cout << getGpioMykonosErrorMessage(error); +        // TODO: make UHD exception +        //throw std::exception(getMykonosErrorMessage(error));      } -    return static_cast<decltype(set_clock_rate(0))>(rate);  } -void ad937x_ctrl::_set_active_tx_chains(bool tx1, bool tx2) +void ad937x_device::_initialize()  { -    decltype(mykonos_config.device->tx->txChannels) newTxChannel; -    if (tx1 && tx2) +    _call_api_function(std::bind(MYKONOS_resetDevice, mykonos_config.device)); +     +    if (get_product_id() != AD9371_PRODUCT_ID)      { -        newTxChannel = TX1_TX2; +        throw uhd::runtime_error("AD9371 product ID does not match expected ID!");      } -    else if (tx1) { -        newTxChannel = TX1; + +    _call_api_function(std::bind(MYKONOS_initialize, mykonos_config.device)); + +    if (!get_pll_lock_status(pll_t::CLK_SYNTH)) +    { +        throw uhd::runtime_error("AD937x CLK_SYNTH PLL failed to lock in initialize()");      } -    else if (tx2) { -        newTxChannel = TX2; + +    std::vector<uint8_t> binary(98304, 0); +    _load_arm(binary); + +    tune(uhd::RX_DIRECTION, RX_DEFAULT_FREQ); +    tune(uhd::TX_DIRECTION, TX_DEFAULT_FREQ); + +    // TODO: wait 200ms or change to polling +    if (!get_pll_lock_status(pll_t::RX_SYNTH)) +    { +        throw uhd::runtime_error("AD937x RX PLL failed to lock in initialize()");      } -    else { -        newTxChannel = TXOFF; +    if (!get_pll_lock_status(pll_t::TX_SYNTH)) +    { +        throw uhd::runtime_error("AD937x TX PLL failed to lock in initialize()");      } -    mykonos_config.device->tx->txChannels = newTxChannel; + +    // TODO: ADD GPIO CTRL setup here +     +    set_gain(uhd::RX_DIRECTION, chain_t::ONE, 0); +    set_gain(uhd::RX_DIRECTION, chain_t::TWO, 0); +    set_gain(uhd::TX_DIRECTION, chain_t::ONE, 0); +    set_gain(uhd::TX_DIRECTION, chain_t::TWO, 0); + +    _run_initialization_calibrations(); + +    // TODO: do external LO leakage calibration here if hardware supports it +    // I don't think we do? + +    _start_jesd(); +    _enable_tracking_calibrations(); +     +    // radio is ON! +    _call_api_function(std::bind(MYKONOS_radioOn, mykonos_config.device)); + +    // TODO: ordering of this doesn't seem right, intuitively, verify this works +    _call_api_function(std::bind(MYKONOS_setObsRxPathSource, mykonos_config.device, OBS_RXOFF)); +    _call_api_function(std::bind(MYKONOS_setObsRxPathSource, mykonos_config.device, OBS_INTERNALCALS));  } -void ad937x_ctrl::_set_active_rx_chains(bool rx1, bool rx2) +// TODO: review const-ness in this function with respect to ADI API +void ad937x_device::_load_arm(std::vector<uint8_t> & binary)  { -    decltype(mykonos_config.device->rx->rxChannels) newRxChannel; -    if (rx1 && rx2) +    _call_api_function(std::bind(MYKONOS_initArm, mykonos_config.device)); + +    if (binary.size() == ARM_BINARY_SIZE)      { -        newRxChannel = RX1_RX2; -    } -    else if (rx1) { -        newRxChannel = RX1; -    } -    else if (rx2) { -        newRxChannel = RX2; -    } -    else { -        newRxChannel = RXOFF; +        throw uhd::runtime_error("ad937x_device ARM is not the correct size!");      } -    mykonos_config.device->rx->rxChannels = newRxChannel; + +    _call_api_function(std::bind(MYKONOS_loadArmFromBinary, mykonos_config.device, &binary[0], binary.size()));  } -void ad937x_ctrl::set_active_chains(direction_t direction, bool channel1, bool channel2) +void ad937x_device::_run_initialization_calibrations()  { -    switch (direction) +    _call_api_function(std::bind(MYKONOS_runInitCals, mykonos_config.device, INIT_CALS)); + +    uint8_t errorFlag = 0; +    uint8_t errorCode = 0; +    _call_api_function( +        std::bind(MYKONOS_waitInitCals,  +            mykonos_config.device,  +            INIT_CAL_TIMEOUT_MS,  +            &errorFlag,  +            &errorCode)); + +    if ((errorFlag != 0) || (errorCode != 0))      { -    case TX: _set_active_tx_chains(channel1, channel2); break; -    case RX: _set_active_rx_chains(channel1, channel2); break; -    default: -        // TODO: bad code path exception -        throw std::exception(); +        mykonosInitCalStatus_t initCalStatus = { 0 }; +        _call_api_function(std::bind(MYKONOS_getInitCalStatus, mykonos_config.device, &initCalStatus)); + +        // abort init cals +        uint32_t initCalsCompleted = 0; +        _call_api_function(std::bind(MYKONOS_abortInitCals, mykonos_config.device, &initCalsCompleted)); +        // init cals completed contains mask of cals that did finish + +        uint16_t errorWord = 0; +        uint16_t statusWord = 0; +        _call_api_function(std::bind(MYKONOS_readArmCmdStatus, mykonos_config.device, &errorWord, &statusWord)); + +        uint8_t status = 0; +        _call_api_function(std::bind(MYKONOS_readArmCmdStatusByte, mykonos_config.device, 2, &status));      } -    // TODO: make this apply the setting  } -double ad937x_ctrl::tune(direction_t direction, const double value) +void ad937x_device::_start_jesd() +{ +    // Stop and/or disable SYSREF +    // ensure BBIC JESD is reset and ready to recieve CGS characters + +    // prepare to transmit CGS when sysref starts +    _call_api_function(std::bind(MYKONOS_enableSysrefToRxFramer, mykonos_config.device, 1)); +         +    // prepare to transmit CGS when sysref starts +    //_call_api_function(std::bind(MYKONOS_enableSysrefToObsRxFramer, mykonos_config.device, 1)); +     +    // prepare to transmit CGS when sysref starts +    _call_api_function(std::bind(MYKONOS_enableSysrefToDeframer, mykonos_config.device, 0)); + +    _call_api_function(std::bind(MYKONOS_resetDeframer, mykonos_config.device)); +    _call_api_function(std::bind(MYKONOS_enableSysrefToDeframer, mykonos_config.device, 1)); + +    // make sure BBIC JESD framer is actively transmitting CGS +    // Start SYSREF + +    // verify sync code here +    // verify links +    uint8_t framerStatus = 0; +    _call_api_function(std::bind(MYKONOS_readRxFramerStatus, mykonos_config.device, &framerStatus)); + +    uint8_t deframerStatus = 0; +    _call_api_function(std::bind(MYKONOS_readDeframerStatus, mykonos_config.device, &deframerStatus)); +} + +void ad937x_device::_enable_tracking_calibrations() +{ +    _call_api_function(std::bind(MYKONOS_enableTrackingCals, mykonos_config.device, TRACKING_CALS)); +} + +ad937x_device::ad937x_device(uhd::spi_iface::sptr iface) : +    full_spi_settings(iface), +    mykonos_config(&full_spi_settings.spi_settings) +{ +    _initialize(); +} + +uint8_t ad937x_device::get_product_id() +{ +    uint8_t id; +    _call_api_function(std::bind(MYKONOS_getProductId, mykonos_config.device, &id)); +    return id; +} + +uint8_t ad937x_device::get_device_rev() +{ +    uint8_t rev; +    _call_api_function(std::bind(MYKONOS_getDeviceRev, mykonos_config.device, &rev)); +    return rev; +} + +ad937x_device::api_version_t ad937x_device::get_api_version()  { -    // I'm not really sure why we set the PLL value in the config AND as a function parameter +    api_version_t api; +    _call_api_function(std::bind(MYKONOS_getApiVersion, +        mykonos_config.device, +        &api.silicon_ver, +        &api.major_ver, +        &api.minor_ver, +        &api.build_ver)); +    return api; +} + +ad937x_device::arm_version_t ad937x_device::get_arm_version() +{ +    arm_version_t arm; +    _call_api_function(std::bind(MYKONOS_getArmVersion, +        mykonos_config.device, +        &arm.major_ver, +        &arm.minor_ver, +        &arm.rc_ver)); +    return arm; +} + +double ad937x_device::set_clock_rate(double req_rate) +{ +    auto rate = static_cast<uint32_t>(req_rate / 1000.0); +    mykonos_config.device->clocks->deviceClock_kHz = rate; +    _call_api_function(std::bind(MYKONOS_initDigitalClocks, mykonos_config.device)); +    return static_cast<double>(rate); +} + +void ad937x_device::enable_channel(uhd::direction_t direction, chain_t chain, bool enable) +{ +    // TODO: +    // Turns out the only code in the API that actually sets the channel enable settings +    // _initialize(). Need to figure out how to deal with this. +} + +double ad937x_device::tune(uhd::direction_t direction, double value) +{ +    // I'm not sure why we set the PLL value in the config AND as a function parameter      // but here it is      mykonosRfPllName_t pll;      uint64_t integer_value = static_cast<uint64_t>(value);      switch (direction)      { -    case TX: +    case uhd::TX_DIRECTION:          pll = TX_PLL;          mykonos_config.device->tx->txPllLoFrequency_Hz = integer_value;          break; -    case RX: +    case uhd::RX_DIRECTION:          pll = RX_PLL;          mykonos_config.device->rx->rxPllLoFrequency_Hz = integer_value;          break;      default: -        // TODO: bad code path exception -        throw std::exception(); +        UHD_THROW_INVALID_CODE_PATH();      } -    { -        std::lock_guard<spi_lock> lock(*spi_l); -        call_api_function(std::bind(MYKONOS_setRfPllFrequency, mykonos_config.device, pll, integer_value)); -    } +    _call_api_function(std::bind(MYKONOS_setRfPllFrequency, mykonos_config.device, pll, integer_value));      // TODO: coercion here causes extra device accesses, when the formula is provided on pg 119 of the user guide      // Furthermore, because coerced is returned as an integer, it's not even accurate      uint64_t coerced_pll; -    { -        std::lock_guard<spi_lock> lock(*spi_l); -        call_api_function(std::bind(MYKONOS_getRfPllFrequency, mykonos_config.device, pll, &coerced_pll)); -    } +    _call_api_function(std::bind(MYKONOS_getRfPllFrequency, mykonos_config.device, pll, &coerced_pll));      return static_cast<double>(coerced_pll);  } -double ad937x_ctrl::get_freq(direction_t direction) +double ad937x_device::get_freq(uhd::direction_t direction)  {      mykonosRfPllName_t pll;      switch (direction)      { -    case TX: pll = TX_PLL; break; -    case RX: pll = RX_PLL; break; +    case uhd::TX_DIRECTION: pll = TX_PLL; break; +    case uhd::RX_DIRECTION: pll = RX_PLL; break;      default: -        // TODO: bad code path exception -        throw std::exception(); +        UHD_THROW_INVALID_CODE_PATH();      }      // TODO: coercion here causes extra device accesses, when the formula is provided on pg 119 of the user guide      // Furthermore, because coerced is returned as an integer, it's not even accurate      uint64_t coerced_pll; +    _call_api_function(std::bind(MYKONOS_getRfPllFrequency, mykonos_config.device, pll, &coerced_pll)); +    return static_cast<double>(coerced_pll); +} + +bool ad937x_device::get_pll_lock_status(pll_t pll) +{ +    uint8_t pll_status; +    _call_api_function(std::bind(MYKONOS_checkPllsLockStatus, mykonos_config.device, &pll_status)); +    switch (pll)      { -        std::lock_guard<spi_lock> lock(*spi_l); -        call_api_function(std::bind(MYKONOS_getRfPllFrequency, mykonos_config.device, pll, &coerced_pll)); +    case pll_t::CLK_SYNTH: +        return (pll_status & 0x01) ? 1 : 0; +    case pll_t::RX_SYNTH: +        return (pll_status & 0x02) ? 1 : 0; +    case pll_t::TX_SYNTH: +        return (pll_status & 0x04) ? 1 : 0; +    case pll_t::SNIFF_SYNTH: +        return (pll_status & 0x08) ? 1 : 0; +    case pll_t::CALPLL_SDM: +        return (pll_status & 0x10) ? 1 : 0; +    default: +        UHD_THROW_INVALID_CODE_PATH(); +        return false;      } -    return static_cast<double>(coerced_pll); +} + +double ad937x_device::set_bw_filter(uhd::direction_t direction, chain_t chain, double value) +{ +    // TODO: implement      return double();  }  // RX Gain values are table entries given in mykonos_user.h  // An array of gain values is programmed at initialization, which the API will then use for its gain values  // In general, Gain Value = (255 - Gain Table Index) -uint8_t ad937x_ctrl::_convert_rx_gain(double inGain, double &coercedGain) +uint8_t ad937x_device::_convert_rx_gain(double gain)  { -    // TODO: use uhd::meta_range? -    const static double min_gain = 0; -    const static double max_gain = 30; -    const static double gain_step = 0.5; - -    coercedGain = inGain; -    if (coercedGain < min_gain) -    { -        coercedGain = min_gain; -    } -    if (coercedGain > max_gain) -    { -        coercedGain = max_gain; -    } - -    // round to nearest step -    coercedGain = std::round(coercedGain * (1.0 / gain_step)) / (1.0 / gain_step); -      // gain should be a value 0-60, add 195 to make 195-255 -    return static_cast<uint8_t>((coercedGain * 2) + 195); +    return static_cast<uint8_t>((gain * 2) + 195);  }  // TX gain is completely different from RX gain for no good reason so deal with it  // TX is set as attenuation using a value from 0-41950 mdB  // Only increments of 50 mdB are valid -uint16_t ad937x_ctrl::_convert_tx_gain(double inGain, double &coercedGain) +uint16_t ad937x_device::_convert_tx_gain(double gain)  { -    // TODO: use uhd::meta_range? -    const static double min_gain = 0; -    const static double max_gain = 41.95; -    const static double gain_step = 0.05; - -    coercedGain = inGain; -    if (coercedGain < min_gain) -    { -        coercedGain = min_gain; -    } -    if (coercedGain > max_gain) -    { -        coercedGain = max_gain; -    } - -    coercedGain = std::round(coercedGain * (1.0 / gain_step)) / (1.0 / gain_step); -      // attenuation is inverted and in mdB not dB -    return static_cast<uint16_t>((max_gain - (coercedGain)) * 1000); +    return static_cast<uint16_t>((MAX_TX_GAIN - (gain)) * 1e3);  } -double ad937x_ctrl::set_gain(direction_t direction, chain_t chain, const double value) +double ad937x_device::set_gain(uhd::direction_t direction, chain_t chain, double value)  {      double coerced_value;      switch (direction)      { -    case TX: +    case uhd::TX_DIRECTION:      { -        uint16_t attenuation = _convert_tx_gain(value, coerced_value); +        uint16_t attenuation = _convert_tx_gain(value); +        coerced_value = static_cast<double>(attenuation); +          std::function<mykonosErr_t(mykonosDevice_t*, uint16_t)> func;          switch (chain)          { -        case CHAIN_1: +        case chain_t::ONE:              func = MYKONOS_setTx1Attenuation;              break; -        case CHAIN_2: +        case chain_t::TWO:              func = MYKONOS_setTx2Attenuation;              break;          default: -            // TODO: bad code path exception -            throw std::exception(); +            UHD_THROW_INVALID_CODE_PATH();          } -        std::lock_guard<spi_lock> lock(*spi_l); -        call_api_function(std::bind(func, mykonos_config.device, attenuation)); +        _call_api_function(std::bind(func, mykonos_config.device, attenuation));          break;      } -    case RX: +    case uhd::RX_DIRECTION:      { -        uint8_t gain = _convert_rx_gain(value, coerced_value); +        uint8_t gain = _convert_rx_gain(value); +        coerced_value = static_cast<double>(gain); +          std::function<mykonosErr_t(mykonosDevice_t*, uint8_t)> func;          switch (chain)          { -        case CHAIN_1: +        case chain_t::ONE:              func = MYKONOS_setRx1ManualGain;              break; -        case CHAIN_2: +        case chain_t::TWO:              func = MYKONOS_setRx2ManualGain;              break;          default: -            // TODO: bad code path exception -            throw std::exception(); +            UHD_THROW_INVALID_CODE_PATH();          } -        std::lock_guard<spi_lock> lock(*spi_l); -        call_api_function(std::bind(func, mykonos_config.device, gain)); +        _call_api_function(std::bind(func, mykonos_config.device, gain));          break;      }      default: -        // TODO: bad code path exception -        throw std::exception(); +        UHD_THROW_INVALID_CODE_PATH();      }      return coerced_value;  } -double ad937x_ctrl::set_agc_mode(direction_t direction, chain_t chain, gain_mode_t mode) +void ad937x_device::set_agc_mode(uhd::direction_t direction, gain_mode_t mode)  { -    std::lock_guard<spi_lock> lock(*spi_l);      switch (direction)      { -    case RX: +    case uhd::RX_DIRECTION:          switch (mode)          { -        case GAIN_MODE_MANUAL: -            call_api_function(std::bind(MYKONOS_resetRxAgc, mykonos_config.device)); +        case gain_mode_t::MANUAL: +            _call_api_function(std::bind(MYKONOS_setRxGainControlMode, mykonos_config.device, MGC)); +            break; +        case gain_mode_t::AUTOMATIC: +            _call_api_function(std::bind(MYKONOS_setRxGainControlMode, mykonos_config.device, AGC));              break; -        case GAIN_MODE_SLOW_AGC: -        case GAIN_MODE_FAST_AGC: -            // TODO: differentiate these -            call_api_function(std::bind(MYKONOS_setupRxAgc, mykonos_config.device)); +        case gain_mode_t::HYBRID: +            _call_api_function(std::bind(MYKONOS_setRxGainControlMode, mykonos_config.device, HYBRID));              break;          default: -            // TODO: bad code path exception -            throw std::exception(); +            UHD_THROW_INVALID_CODE_PATH();          }      default: -        // TODO: bad code path exception -        throw std::exception(); +        UHD_THROW_INVALID_CODE_PATH(); +    } +} + +void ad937x_device::set_fir( +    const uhd::direction_t direction,  +    const chain_t chain,  +    int8_t gain,  +    const std::vector<int16_t> & fir) +{ +    switch (direction) +    { +    case uhd::TX_DIRECTION: +        mykonos_config.tx_fir_config.set_fir(gain, fir); +        break; +    case uhd::RX_DIRECTION: +        mykonos_config.rx_fir_config.set_fir(gain, fir); +        break; +    default: +        UHD_THROW_INVALID_CODE_PATH();      } -    return double();  } -ad937x_ctrl::sptr ad937x_ctrl::make(spi_lock::sptr spi_l, mpm::spi_iface::sptr iface) +std::vector<int16_t> ad937x_device::get_fir( +    const uhd::direction_t direction,  +    const chain_t chain,  +    int8_t &gain)  { -    return std::make_shared<ad937x_ctrl>(spi_l, iface); +    switch (direction) +    { +    case uhd::TX_DIRECTION: +        return mykonos_config.tx_fir_config.get_fir(gain); +    case uhd::RX_DIRECTION: +        return mykonos_config.rx_fir_config.get_fir(gain); +    default: +        UHD_THROW_INVALID_CODE_PATH(); +    }  } -*/ + +int16_t ad937x_device::get_temperature() +{ +    // TODO: deal with the status.tempValid flag +    mykonosTempSensorStatus_t status; +    _call_gpio_api_function(std::bind(MYKONOS_readTempSensor, mykonos_config.device, &status)); +    return status.tempCode; +} + diff --git a/mpm/lib/mykonos/ad937x_device.hpp b/mpm/lib/mykonos/ad937x_device.hpp index c2d159be9..52d25abba 100644 --- a/mpm/lib/mykonos/ad937x_device.hpp +++ b/mpm/lib/mykonos/ad937x_device.hpp @@ -1,92 +1,103 @@ +// +// 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/>. +// +  #pragma once +#include "config/ad937x_config_t.hpp" +#include "config/ad937x_fir.hpp" +#include "adi/t_mykonos.h" +#include "adi/t_mykonos_gpio.h" +#include "mpm/spi/adi_ctrl.hpp" +  // TODO: fix path of UHD includes  #include <../../host/include/uhd/types/direction.hpp>  #include <../../host/include/uhd/types/ranges.hpp>  #include <../../host/include/uhd/exception.hpp> -#include "config/ad937x_config_t.hpp" -#include "config/ad937x_fir.h" -#include "adi/t_mykonos.h" -#include "../spi/spi_lock.h" -#include "../spi/spi_config.h" -#include <mpm/spi_iface.hpp> -#include <mpm/spi/adi_ctrl.hpp>  #include <boost/noncopyable.hpp> +#include <mutex> +#include <memory>  #include <functional> -struct ad937x_api_version_t { -    uint32_t silicon_ver; -    uint32_t major_ver; -    uint32_t minor_ver; -    uint32_t build_ver; -}; - -struct ad937x_arm_version_t { -    uint32_t major_ver; -    uint32_t minor_ver; -    uint32_t rc_ver; -}; -  class ad937x_device : public boost::noncopyable  {  public: +    struct api_version_t { +        uint32_t silicon_ver; +        uint32_t major_ver; +        uint32_t minor_ver; +        uint32_t build_ver; +    }; + +    struct arm_version_t { +        uint8_t major_ver; +        uint8_t minor_ver; +        uint8_t rc_ver; +    }; +      enum class gain_mode_t { MANUAL, AUTOMATIC, HYBRID };      enum class chain_t { ONE, TWO }; +    enum class pll_t {CLK_SYNTH, RX_SYNTH, TX_SYNTH, SNIFF_SYNTH, CALPLL_SDM};      typedef std::shared_ptr<ad937x_device> sptr; -    virtual ~ad937x_device(void) {}; -     -    static uhd::meta_range_t get_rf_freq_range(void); -    static uhd::meta_range_t get_bw_filter_range(void); -    static std::vector<double> get_clock_rates(void); +    ad937x_device(uhd::spi_iface::sptr iface); -    uhd::meta_range_t get_gain_range(uhd::direction_t direction, chain_t chain); +    uint8_t get_product_id(); +    uint8_t get_device_rev(); +    api_version_t get_api_version(); +    arm_version_t get_arm_version(); -    uint8_t get_product_id() = 0; -    uint8_t get_device_rev() = 0; -    ad937x_api_version_t get_api_version() = 0; -    ad937x_arm_version_t get_arm_version() = 0; +    double set_bw_filter(uhd::direction_t direction, chain_t chain, double value); +    double set_gain(uhd::direction_t direction, chain_t chain, double value); +    void set_agc_mode(uhd::direction_t direction, gain_mode_t mode); +    double set_clock_rate(double value); +    void enable_channel(uhd::direction_t direction, chain_t chain, bool enable); +    double tune(uhd::direction_t direction, double value); +    double get_freq(uhd::direction_t direction); -    double set_bw_filter(const uhd::direction_t direction, const chain_t chain, const double value) = 0; -    double set_gain(const uhd::direction_t direction, const chain_t chain, const double value) = 0; +    bool get_pll_lock_status(pll_t pll); -    void set_agc(const uhd::direction_t direction, const bool enable) = 0; -    void set_agc_mode(const uhd::direction_t direction, const gain_mode_t mode) = 0; +    void set_fir(uhd::direction_t direction, chain_t chain, int8_t gain, const std::vector<int16_t> & fir); +    std::vector<int16_t> get_fir(uhd::direction_t direction, chain_t chain, int8_t &gain); -    double set_clock_rate(const double value) = 0; -    void enable_channel(const uhd::direction_t direction, const chain_t chain, const bool enable) = 0; +    int16_t get_temperature();     -    double tune(const uhd::direction_t direction, const double value) = 0; -    double get_freq(const uhd::direction_t direction) = 0; - -    void set_fir(const uhd::direction_t direction, const chain_t chain, const ad937x_fir & fir) = 0; -    ad937x_fir get_fir(const uhd::direction_t direction, const chain_t chain) = 0; - -    int16_t get_temperature() = 0;     - -private:      const static double MIN_FREQ;      const static double MAX_FREQ; +    const static double MIN_RX_GAIN; +    const static double MAX_RX_GAIN; +    const static double RX_GAIN_STEP; +    const static double MIN_TX_GAIN; +    const static double MAX_TX_GAIN; +    const static double TX_GAIN_STEP; -    virtual void initialize() = 0; - -    spi_lock::sptr spi_l; -    mpm::spi_iface::sptr iface; -    mpm_spiSettings_t mpm_sps; +private: +    void _initialize(); +    void _load_arm(std::vector<uint8_t> & binary); +    void _run_initialization_calibrations(); +    void _start_jesd(); +    void _enable_tracking_calibrations(); +    ad9371_spiSettings_t full_spi_settings;      ad937x_config_t mykonos_config; -    void call_api_function(std::function<mykonosErr_t()> func); - -    static uint8_t _convert_rx_gain(double inGain, double &coercedGain); -    static uint16_t _convert_tx_gain(double inGain, double &coercedGain); - -    void _set_active_tx_chains(bool tx1, bool tx2); -    void _set_active_rx_chains(bool rx1, bool rx2); - -    const static spi_device_settings_t spi_device_settings; -}; +    void _call_api_function(std::function<mykonosErr_t()> func); +    void _call_gpio_api_function(std::function<mykonosGpioErr_t()> func); -const double ad937x_ctrl::MIN_FREQ = 300e6; -const double ad937x_ctrl::MAX_FREQ = 6e9;
\ No newline at end of file +    static uint8_t _convert_rx_gain(double gain); +    static uint16_t _convert_tx_gain(double gain); +};
\ No newline at end of file diff --git a/mpm/lib/mykonos/adi/CMakeLists.txt b/mpm/lib/mykonos/adi/CMakeLists.txt index 596344eb8..b54a604b9 100644 --- a/mpm/lib/mykonos/adi/CMakeLists.txt +++ b/mpm/lib/mykonos/adi/CMakeLists.txt @@ -2,5 +2,4 @@ MYKONOS_APPEND_SOURCES(      ${CMAKE_CURRENT_SOURCE_DIR}/mykonos.c      ${CMAKE_CURRENT_SOURCE_DIR}/mykonos_gpio.c      ${CMAKE_CURRENT_SOURCE_DIR}/mykonos_user.c -    ${CMAKE_CURRENT_SOURCE_DIR}/mykonosMmap.c  ) diff --git a/mpm/lib/mykonos/adi/common.h b/mpm/lib/mykonos/adi/common.h index f39f20ce1..5268b2a8b 100644 --- a/mpm/lib/mykonos/adi/common.h +++ b/mpm/lib/mykonos/adi/common.h @@ -91,9 +91,9 @@ commonErr_t CMB_SPIReadField (spiSettings_t *spiSettings, uint16_t addr, uint8_t  /* platform timer functions */  commonErr_t CMB_wait_ms(uint32_t time_ms);  commonErr_t CMB_wait_us(uint32_t time_us); -commonErr_t CMB_setTimeout_ms(uint32_t timeOut_ms); -commonErr_t CMB_setTimeout_us(uint32_t timeOut_us); -commonErr_t CMB_hasTimeoutExpired(); +commonErr_t CMB_setTimeout_ms(spiSettings_t *spiSettings, uint32_t timeOut_ms); +commonErr_t CMB_setTimeout_us(spiSettings_t *spiSettings, uint32_t timeOut_us); +commonErr_t CMB_hasTimeoutExpired(spiSettings_t *spiSettings);  /* platform logging functions */  commonErr_t CMB_openLog(const char *filename); diff --git a/mpm/lib/mykonos/adi/mykonos.c b/mpm/lib/mykonos/adi/mykonos.c index 4688388ff..f27a03800 100644 --- a/mpm/lib/mykonos/adi/mykonos.c +++ b/mpm/lib/mykonos/adi/mykonos.c @@ -1702,7 +1702,7 @@ mykonosErr_t MYKONOS_waitForEvent(mykonosDevice_t *device, waitEvent_t waitEvent              return MYKONOS_ERR_WAITFOREVENT_INV_PARM;      } -    CMB_setTimeout_us(timeout_us); /* timeout after desired time */ +    CMB_setTimeout_us(device->spiSettings, timeout_us); /* timeout after desired time */      do      { @@ -1720,7 +1720,7 @@ mykonosErr_t MYKONOS_waitForEvent(mykonosDevice_t *device, waitEvent_t waitEvent          }  #endif -        if (CMB_hasTimeoutExpired() > 0) +        if (CMB_hasTimeoutExpired(device->spiSettings) > 0)          {              CMB_writeToLog(ADIHAL_LOG_WARNING, device->spiSettings->chipSelectIndex, errCode, getMykonosErrorMessage(errCode));              return errCode; @@ -13155,14 +13155,14 @@ mykonosErr_t MYKONOS_verifyArmChecksum(mykonosDevice_t *device)      buildTimeChecksum = (((uint32_t)buildData[3] << 24) | ((uint32_t)buildData[2] << 16) | ((uint32_t)buildData[1] << 8) | (uint32_t)buildData[0]);      /* using 200 msec timeout for exit out of while loop [maximum checksum calculation time = 5 ms] */ -    CMB_setTimeout_ms(200); +    CMB_setTimeout_ms(device->spiSettings, 200);      /* determining calculated checksum */      do      {          MYKONOS_readArmMem(device, MYKONOS_ADDR_ARM_CALC_CHKSUM_ADDR, calcData, CHECKSUM_BYTES, 0);          calculatedChecksum = (((uint32_t)calcData[3] << 24) | ((uint32_t)calcData[2] << 16) | ((uint32_t)calcData[1] << 8) | (uint32_t)calcData[0]); -    } while ((!calculatedChecksum) && (!CMB_hasTimeoutExpired())); +    } while ((!calculatedChecksum) && (!CMB_hasTimeoutExpired(device->spiSettings)));      /* performing consistency check */      if (buildTimeChecksum == calculatedChecksum) @@ -13204,7 +13204,7 @@ mykonosErr_t MYKONOS_checkArmState(mykonosDevice_t *device, mykonosArmState_t ar      CMB_writeToLog(ADIHAL_LOG_MESSAGE, device->spiSettings->chipSelectIndex, MYKONOS_ERR_OK, "MYKONOS_checkArmState()\n");  #endif -    CMB_setTimeout_ms(timeoutMs); +    CMB_setTimeout_ms(device->spiSettings, timeoutMs);      do      { @@ -13220,7 +13220,7 @@ mykonosErr_t MYKONOS_checkArmState(mykonosDevice_t *device, mykonosArmState_t ar              break;          } -        if (CMB_hasTimeoutExpired()) +        if (CMB_hasTimeoutExpired(device->spiSettings))          {              CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_WAITARMCSTATE_TIMEOUT,                      getMykonosErrorMessage(MYKONOS_ERR_WAITARMCSTATE_TIMEOUT)); @@ -15602,13 +15602,13 @@ mykonosErr_t MYKONOS_sendArmCommand(mykonosDevice_t *device, uint8_t opCode, uin      }      /* setting a 2 sec timeout for mailbox busy bit to be clear (can't send an arm mailbox command until mailbox is ready) */ -    CMB_setTimeout_ms(2000); +    CMB_setTimeout_ms(device->spiSettings, 2000);      do      {          CMB_SPIReadField(device->spiSettings, MYKONOS_ADDR_ARM_CMD, &armCommandBusy, 0x80, 7); -        if (CMB_hasTimeoutExpired()) +        if (CMB_hasTimeoutExpired(device->spiSettings))          {              CMB_writeToLog(ADIHAL_LOG_ERROR, device->spiSettings->chipSelectIndex, MYKONOS_ERR_TIMEDOUT_ARMMAILBOXBUSY,                      getMykonosErrorMessage(MYKONOS_ERR_TIMEDOUT_ARMMAILBOXBUSY)); @@ -15795,7 +15795,7 @@ mykonosErr_t MYKONOS_waitArmCmdStatus(mykonosDevice_t *device, uint8_t opCode, u      }      /* start wait */ -    CMB_setTimeout_ms(timeoutMs); +    CMB_setTimeout_ms(device->spiSettings, timeoutMs);      do      { @@ -15809,7 +15809,7 @@ mykonosErr_t MYKONOS_waitArmCmdStatus(mykonosDevice_t *device, uint8_t opCode, u              return MYKONOS_ERR_ARMCMDSTATUS_ARMERROR;          } -        if (CMB_hasTimeoutExpired()) +        if (CMB_hasTimeoutExpired(device->spiSettings))          {              return MYKONOS_ERR_WAITARMCMDSTATUS_TIMEOUT;          } diff --git a/mpm/lib/mykonos/adi/mykonosMmap.c b/mpm/lib/mykonos/adi/mykonosMmap.c deleted file mode 100644 index f88cbb3a3..000000000 --- a/mpm/lib/mykonos/adi/mykonosMmap.c +++ /dev/null @@ -1,129 +0,0 @@ -/** - * \file mykonosMmap.c - * \brief Contains the Mykonos memory mapping - * - * Mykonos API version: 1.3.1.3534 - */ - -#include <stdint.h> -uint8_t mykonosMmap [] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x13,0x03,0x03,0x13,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, -                                 0x00,0xE4,0xE4,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA5,0xA5,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x01,0x00,0xE4,0xE4,0x00,0x00,0x00,0x1F,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9F,0xE0,0x20,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xF5,0x8F,0x0F,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -                                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; -/*!< Mykonos memory map */ diff --git a/mpm/lib/mykonos/adi_ctrl.cpp b/mpm/lib/mykonos/adi_ctrl.cpp index d25c2b188..305e4f711 100644 --- a/mpm/lib/mykonos/adi_ctrl.cpp +++ b/mpm/lib/mykonos/adi_ctrl.cpp @@ -15,123 +15,181 @@  // along with this program.  If not, see <http://www.gnu.org/licenses/>.  // +  #include "adi/common.h"  #include <mpm/spi/adi_ctrl.hpp> -#include <mpm/spi_iface.hpp> + +// TODO: fix path of UHD includes +#include <../../host/include/uhd/exception.hpp>  #include <iostream> -//#include <boost/format.hpp> +#include <chrono> +#include <thread> -#define CMB_TRACE_FUNCTIONS 0 +ad9371_spiSettings_t::ad9371_spiSettings_t(uhd::spi_iface::sptr uhd_iface) : +    spi_iface(uhd_iface) +{ +    spi_settings.chipSelectIndex = 0;       // set later +    spi_settings.writeBitPolarity = 1;      // unused +    spi_settings.longInstructionWord = 1;    +    spi_settings.MSBFirst = 1;               +    spi_settings.CPHA = 0;                   +    spi_settings.CPOL = 0;                   +    spi_settings.enSpiStreaming = 0;        // unused +    spi_settings.autoIncAddrUp = 0;         // unused +    spi_settings.fourWireMode = 1;          // unused +    spi_settings.spiClkFreq_Hz = 250000000; // currently unused +} -#if CMB_TRACE_FUNCTIONS == 1 -#define CMB_TRACE_FUNCTION std::cout << __FUNCTION__ << std::endl; -#else -#define CMB_TRACE_FUNCTION -#endif +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 */ +// close hardware pointers  commonErr_t CMB_closeHardware(void)  { -    CMB_TRACE_FUNCTION; -    return COMMONERR_OK; +    // not implemented +    return COMMONERR_FAILED;  } -/* GPIO function */ +// GPIO function  commonErr_t CMB_setGPIO(uint32_t GPIO)  { -    CMB_TRACE_FUNCTION; -    return COMMONERR_OK; +    // not implemented +    return COMMONERR_FAILED;  } -/* hardware reset function */ +// hardware reset function  commonErr_t CMB_hardReset(uint8_t spiChipSelectIndex)  { -    CMB_TRACE_FUNCTION; -    //std::cout << "Hard reset chip select " << spiChipSelectIndex << std::endl; +    // TODO: implement      return COMMONERR_OK;  } -/* SPI read/write functions */ +// +// SPI read/write functions +// -/* allows the platform HAL to work with devices with various SPI settings */ +// allows the platform HAL to work with devices with various SPI settings  commonErr_t CMB_setSPIOptions(spiSettings_t *spiSettings)  { -    CMB_TRACE_FUNCTION; +    // not implemented      return COMMONERR_OK;  } -/* value of 0 deasserts all chip selects */ +// value of 0 deasserts all chip selects  commonErr_t CMB_setSPIChannel(uint16_t chipSelectIndex)  { -    CMB_TRACE_FUNCTION; +    // not implemented      return COMMONERR_OK;  } -/* single SPI byte write function */ +// single SPI byte write function  commonErr_t CMB_SPIWriteByte(spiSettings_t *spiSettings, uint16_t addr, uint8_t data)  { -    mpm_spiSettings_t *mpm_spi = mpm_spiSettings_t::make(spiSettings); +    // TODO: crash and burn for these errors? +    if (spiSettings == nullptr || spiSettings->MSBFirst == 0) 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);      try { -        mpm_spi->spi_iface->write_byte(addr, data); +        mpm_spi->spi_iface->write_spi(spiSettings->chipSelectIndex, config, data_word, 24);          return COMMONERR_OK;      } catch (const std::exception &e) { -        /* ... error handling ... */ +        // ... error handling ...      }      return COMMONERR_FAILED;  }  commonErr_t CMB_SPIWriteBytes(spiSettings_t *spiSettings, uint16_t *addr, uint8_t *data, uint32_t count)  { -    mpm_spiSettings_t *mpm_spi = mpm_spiSettings_t::make(spiSettings); +    // TODO: crash and burn for these errors? +    if (spiSettings == nullptr || +        addr == nullptr || +        data == nullptr || +        spiSettings->MSBFirst == 0) +    { +        return COMMONERR_FAILED; +    } + +    ad9371_spiSettings_t *mpm_spi = ad9371_spiSettings_t::make(spiSettings); +    uhd::spi_config_t config(_get_edge(*spiSettings));      try { -        mpm_spi->spi_iface->write_bytes(addr, data, count); +        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); +        }          return COMMONERR_OK;      } catch (const std::exception &e) { -        /* ... error handling ... */ +        // ... error handling ...      }      return COMMONERR_FAILED;  } -/* single SPI byte read function */ +// single SPI byte read function  commonErr_t CMB_SPIReadByte (spiSettings_t *spiSettings, uint16_t addr, uint8_t *readdata)  { -    mpm_spiSettings_t *mpm_spi = mpm_spiSettings_t::make(spiSettings); +    if (spiSettings == nullptr || +        readdata == nullptr || +        spiSettings->MSBFirst == 0) +    { +        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); +          try { -        *readdata = mpm_spi->spi_iface->read_byte(addr); +        *readdata = static_cast<uint8_t>( +            mpm_spi->spi_iface->read_spi(spiSettings->chipSelectIndex, config, data_word, 24));          return COMMONERR_OK;      } catch (const std::exception &e) { -        /* ... error handling ... */ +        // ... error handling ...      }      return COMMONERR_FAILED;  } -/* write a field in a single register */ +// write a field in a single register  commonErr_t CMB_SPIWriteField(          spiSettings_t *spiSettings,          uint16_t addr, uint8_t  field_val,          uint8_t mask, uint8_t start_bit  ) { -    mpm_spiSettings_t *mpm_spi = mpm_spiSettings_t::make(spiSettings); +    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); +      try { -        mpm_spi->spi_iface->write_field(addr, field_val, mask, start_bit); +        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);          return COMMONERR_OK;      } catch (const std::exception &e) { -        /* ... error handling ... */ +        // ... error handling ...      }      return COMMONERR_FAILED;  } -/* read a field in a single register */ +// read a field in a single register  commonErr_t CMB_SPIReadField(          spiSettings_t *spiSettings,          uint16_t addr, uint8_t *field_val,          uint8_t mask, uint8_t start_bit  ) { -    mpm_spiSettings_t *mpm_spi = mpm_spiSettings_t::make(spiSettings); +    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); +      try { -        *field_val = mpm_spi->spi_iface->read_field(addr, mask, start_bit); +        uint32_t value = mpm_spi->spi_iface->read_spi(spiSettings->chipSelectIndex, config, read_word, 24); +        *field_val = static_cast<uint8_t>((value & mask) >> start_bit);          return COMMONERR_OK;      } catch (const std::exception &e) {          /* ... error handling ... */ @@ -139,77 +197,89 @@ commonErr_t CMB_SPIReadField(      return COMMONERR_FAILED;  } -/* platform timer functions */ +// platform timer functions +  commonErr_t CMB_wait_ms(uint32_t time_ms)  { -    CMB_TRACE_FUNCTION; +    std::this_thread::sleep_for(std::chrono::milliseconds(time_ms));      return COMMONERR_OK;  }  commonErr_t CMB_wait_us(uint32_t time_us)  { -    CMB_TRACE_FUNCTION; +    std::this_thread::sleep_for(std::chrono::microseconds(time_us));      return COMMONERR_OK;  } -commonErr_t CMB_setTimeout_ms(uint32_t timeOut_ms) + +commonErr_t CMB_setTimeout_ms(spiSettings_t *spiSettings, uint32_t timeOut_ms)  { -    CMB_TRACE_FUNCTION; +    ad9371_spiSettings_t *mpm_spi = ad9371_spiSettings_t::make(spiSettings); +    mpm_spi->timeout_start = std::chrono::steady_clock::now(); +    mpm_spi->timeout_duration = std::chrono::milliseconds(timeOut_ms);      return COMMONERR_OK;  } -commonErr_t CMB_setTimeout_us(uint32_t timeOut_us) +commonErr_t CMB_setTimeout_us(spiSettings_t *spiSettings, uint32_t timeOut_us)  { -    CMB_TRACE_FUNCTION; +    ad9371_spiSettings_t *mpm_spi = ad9371_spiSettings_t::make(spiSettings); +    mpm_spi->timeout_start = std::chrono::steady_clock::now(); +    mpm_spi->timeout_duration = std::chrono::microseconds(timeOut_us);      return COMMONERR_OK;  } -commonErr_t CMB_hasTimeoutExpired() +commonErr_t CMB_hasTimeoutExpired(spiSettings_t *spiSettings)  { -    CMB_TRACE_FUNCTION; -    return COMMONERR_FAILED; +    ad9371_spiSettings_t *mpm_spi = ad9371_spiSettings_t::make(spiSettings); +    auto current_time = std::chrono::steady_clock::now(); +    if ((std::chrono::steady_clock::now() - mpm_spi->timeout_start) > mpm_spi->timeout_duration) +    { +        return COMMONERR_FAILED; +    } +    else { +        return COMMONERR_OK; +    }  } -/* platform logging functions */ +// platform logging functions  commonErr_t CMB_openLog(const char *filename)  { -    CMB_TRACE_FUNCTION; -    return COMMONERR_OK; +    // not implemented +    return COMMONERR_FAILED;  }  commonErr_t CMB_closeLog(void)  { -    CMB_TRACE_FUNCTION; -    return COMMONERR_OK; +    // not implemented +    return COMMONERR_FAILED;  }  commonErr_t CMB_writeToLog(ADI_LOGLEVEL level, uint8_t deviceIndex, uint32_t errorCode, const char *comment)  { -    CMB_TRACE_FUNCTION;      std::cout << level << " " << errorCode << " " << comment << std::endl;      return COMMONERR_OK;  }  commonErr_t CMB_flushLog(void)  { -    CMB_TRACE_FUNCTION; -    return COMMONERR_OK; +    // not implemented +    return COMMONERR_FAILED;  }  /* platform FPGA AXI register read/write functions */  commonErr_t CMB_regRead(uint32_t offset, uint32_t *data)  { -    CMB_TRACE_FUNCTION; -    return COMMONERR_OK; +    // not implemented +    return COMMONERR_FAILED;  }  commonErr_t CMB_regWrite(uint32_t offset, uint32_t data)  { -    CMB_TRACE_FUNCTION; -    return COMMONERR_OK; +    // not implemented +    return COMMONERR_FAILED;  }  /* platform DDR3 memory read/write functions */  commonErr_t CMB_memRead(uint32_t offset, uint32_t *data, uint32_t len)  { -    CMB_TRACE_FUNCTION; -    return COMMONERR_OK; +    // not implemented +    return COMMONERR_FAILED;  }  commonErr_t CMB_memWrite(uint32_t offset, uint32_t *data, uint32_t len)  { -    CMB_TRACE_FUNCTION; -    return COMMONERR_OK; +    // not implemented +    return COMMONERR_FAILED;  } diff --git a/mpm/lib/mykonos/adi_sample/CMakeLists.txt b/mpm/lib/mykonos/adi_sample/CMakeLists.txt deleted file mode 100644 index e00c31032..000000000 --- a/mpm/lib/mykonos/adi_sample/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -MYKONOS_APPEND_SOURCES( -    ${CMAKE_CURRENT_SOURCE_DIR}/headless.cpp -    ${CMAKE_CURRENT_SOURCE_DIR}/mykonos_static_config.c -) diff --git a/mpm/lib/mykonos/adi_sample/headless.c b/mpm/lib/mykonos/adi_sample/headless.c deleted file mode 100644 index 9fedc9338..000000000 --- a/mpm/lib/mykonos/adi_sample/headless.c +++ /dev/null @@ -1,528 +0,0 @@ -/** - * \file headless.c - * - * \brief Contains example code for user integration with their application - * - * All data structures required for operation have been initialized with values which reflect - * these settings: - * - * Device Clock: - * 125MHz - * - * Profiles: - * Rx 100MHz, IQrate 125MSPS, Dec5 - * Tx 20/100MHz, IQrate 125MSPS, Dec5 - * ORX 100MHz, IQrate 125MSPS, Dec5 - * SRx 20MHz, IQrate 31.25MSPS, Dec5 - * - */ - -#include <stdlib.h> -#include "headless.h" -#include "t_mykonos.h" -#include "mykonos.h" -#include "mykonos_gpio.h" -#include "mykonos_config.h" -//#include "mykonos_static_config.h" - -/****< Action: Insert rest of required Includes Here >***/ - -int oldmain() -{ -	const char* errorString; -	uint8_t mcsStatus = 0; -	uint8_t pllLockStatus = 0; -	uint8_t binary[98304] = {0};  /*** < Action: binary should contain ARM binary file as array  > ***/ -	uint32_t count = sizeof(binary); -	uint8_t errorFlag = 0; -	uint8_t errorCode = 0; -	uint32_t initCalsCompleted = 0; -	uint16_t errorWord = 0; -	uint16_t statusWord = 0; -	uint8_t status = 0; -	mykonosInitCalStatus_t initCalStatus = {0}; - -	uint8_t deframerStatus = 0; -	uint8_t obsFramerStatus = 0; -	uint8_t framerStatus = 0; -	uint32_t initCalMask = TX_BB_FILTER | ADC_TUNER | TIA_3DB_CORNER | DC_OFFSET | -	TX_ATTENUATION_DELAY | RX_GAIN_DELAY | FLASH_CAL | -	PATH_DELAY | TX_LO_LEAKAGE_INTERNAL | TX_QEC_INIT | -	LOOPBACK_RX_LO_DELAY | LOOPBACK_RX_RX_QEC_INIT | -	RX_LO_DELAY | RX_QEC_INIT; - -	uint32_t trackingCalMask = 	TRACK_RX1_QEC | -	TRACK_RX2_QEC | -	TRACK_TX1_QEC | -	TRACK_TX2_QEC | -	TRACK_ORX1_QEC| -	TRACK_ORX2_QEC; - -	mykonosErr_t mykError = MYKONOS_ERR_OK; -	mykonosGpioErr_t mykGpioErr = MYKONOS_ERR_GPIO_OK; - -	/* Allocating memory for the errorString */ -	errorString = (const char*) malloc(sizeof(char) * 200); - -	/*** < Action: Insert System Clock(s) Initialization Code Here          > ***/ - -	/*** < Action: Insert BBIC Initialization Code Here                     > ***/ - -	/*************************************************************************/ -	/*****                Mykonos Initialization Sequence                *****/ -	/*************************************************************************/ - -    // TODO: change to unique ptr -    mykonos_config config(); -    mykonosDevice_t *mykDevice = &config.device; - - -	/*** < Action: Toggle RESETB pin on Mykonos device                   > ***/ -	if ((mykError = MYKONOS_resetDevice(&mykDevice)) != MYKONOS_ERR_OK) -    { -        /*** < Info: errorString will contain log error string in order to debug failure > ***/ -	    errorString = getMykonosErrorMessage(mykError); -    } - -	if ((mykError = MYKONOS_initialize(&mykDevice)) != MYKONOS_ERR_OK) -	{ -	    /*** < Info: errorString will contain log error string in order to debug failure > ***/ -	    errorString = getMykonosErrorMessage(mykError); -	} - -	/*************************************************************************/ -	/*****                Mykonos CLKPLL Status Check                    *****/ -	/*************************************************************************/ -	if ((mykError = MYKONOS_checkPllsLockStatus(&mykDevice, &pllLockStatus)) != MYKONOS_ERR_OK) -    { -        /*** < Info: errorString will contain log error string in order to debug failure > ***/ -	    errorString = getMykonosErrorMessage(mykError); -    } - -	if (pllLockStatus & 0x01) -	{ -		/*** < User: code here for actions once CLKPLL locked  > ***/ -	} -	else -	{ -		/*** < User: code here here for actions since CLKPLL not locked -		 * ensure lock before proceeding - > ***/ -	} - -	/*************************************************************************/ -	/*****                Mykonos Perform MultiChip Sync                 *****/ -	/*************************************************************************/ -	if ((mykError = MYKONOS_enableMultichipSync(&mykDevice, 1, &mcsStatus)) != MYKONOS_ERR_OK) -    { -        /*** < Info: errorString will contain log error string in order to debug failure > ***/ -	    errorString = getMykonosErrorMessage(mykError); -    } - - -	/*** < Action: minimum 3 SYSREF pulses from Clock Device has to be produced -	 * for MulticChip Sync > ***/ - -	/*************************************************************************/ -	/*****                Mykonos Verify MultiChip Sync                 *****/ -	/*************************************************************************/ -	if ((mykError = MYKONOS_enableMultichipSync(&mykDevice, 0, &mcsStatus)) != MYKONOS_ERR_OK) -    { -	    /*** < Info: errorString will contain log error string in order to debug failure > ***/ -	    errorString = getMykonosErrorMessage(mykError); -    } - -	if ((mcsStatus & 0x0B) == 0x0B) -	{ -		/*** < Info: MCS successful  > ***/ -	    /*** < Action: extra User code   > ***/ -	} -	else -	{ -	    /*** < Info: MCS failed  > ***/ -		/*** < Action: ensure MCS before proceeding  > ***/ -	} - -	/*************************************************************************/ -	/*****                Mykonos Load ARM file                          *****/ -	/*************************************************************************/ -	if (pllLockStatus & 0x01) -	{ -		if ((mykError = MYKONOS_initArm(&mykDevice)) != MYKONOS_ERR_OK) -        { -            /*** < Info: errorString will contain log error string in order to debug failure > ***/ -		    errorString = getMykonosErrorMessage(mykError); -        } - -		/*** < Action: User must load ARM binary byte array into variable binary[98304] before calling next command > ***/ -		if ((mykError = MYKONOS_loadArmFromBinary(&mykDevice, &binary[0], count)) != MYKONOS_ERR_OK) -		{ -		    /*** < Info: errorString will contain log error string in order to debug why -		     *  ARM did not load properly - check binary and device settings  > ***/ -		    /*** < Action: User code > ***/ -		    errorString = getMykonosErrorMessage(mykError); -		} - -	} -	else -	{ -		/*** < Action: check settings for proper CLKPLL lock > ***/ -	} - -	/*************************************************************************/ -	/*****                Mykonos Set RF PLL Frequencies                 *****/ -	/*************************************************************************/ -	if ((mykError = MYKONOS_setRfPllFrequency(&mykDevice, RX_PLL, mykDevice.rx->rxPllLoFrequency_Hz)) != MYKONOS_ERR_OK) -    { -        /*** < Info: errorString will contain log error string in order to debug failure > ***/ -        errorString = getMykonosErrorMessage(mykError); -    } - -	if ((mykError = MYKONOS_setRfPllFrequency(&mykDevice, TX_PLL, mykDevice.tx->txPllLoFrequency_Hz)) != MYKONOS_ERR_OK) -    { -        /*** < Info: errorString will contain log error string in order to debug failure > ***/ -	    errorString = getMykonosErrorMessage(mykError); -    } - -	if ((mykError = MYKONOS_setRfPllFrequency(&mykDevice, SNIFFER_PLL, mykDevice.obsRx->snifferPllLoFrequency_Hz)) != MYKONOS_ERR_OK) -    { -        /*** < Info: errorString will contain log error string in order to debug failure > ***/ -	    errorString = getMykonosErrorMessage(mykError); -    } - -	/*** < Action: wait 200ms for PLLs to lock > ***/ - -	if ((mykError = MYKONOS_checkPllsLockStatus(&mykDevice, &pllLockStatus)) != MYKONOS_ERR_OK) -    { -        /*** < Info: errorString will contain log error string in order to debug failure > ***/ -	    errorString = getMykonosErrorMessage(mykError); -    } - -	if ((pllLockStatus & 0x0F) == 0x0F) -	{ -	    /*** < Info: All PLLs locked > ***/ -	} -	else -	{ -	    /*** < Info: PLLs not locked  > ***/ -	    /*** < Action: Ensure lock before proceeding - User code here > ***/ -	} - -	/*************************************************************************/ -	/*****                Mykonos Set GPIOs                              *****/ -	/*************************************************************************/ -	if ((mykGpioErr = MYKONOS_setRx1GainCtrlPin(&mykDevice, 0, 0, 0, 0, 0)) != MYKONOS_ERR_GPIO_OK) -    { -        /*** < Info: errorString will contain log error string in order to debug failure > ***/ -	    errorString = getGpioMykonosErrorMessage(mykGpioErr); -    } - -	if ((mykGpioErr = MYKONOS_setRx2GainCtrlPin(&mykDevice, 0, 0, 0, 0, 0)) != MYKONOS_ERR_GPIO_OK) -    { -        /*** < Info: errorString will contain log error string in order to debug failure > ***/ -	    errorString = getGpioMykonosErrorMessage(mykGpioErr); -    } - -	if ((mykGpioErr = MYKONOS_setTx1AttenCtrlPin(&mykDevice, 0, 0, 0, 0, 0)) != MYKONOS_ERR_GPIO_OK) -    { -        /*** < Info: errorString will contain log error string in order to debug failure > ***/ -	    errorString = getGpioMykonosErrorMessage(mykGpioErr); -    } - -	if ((mykGpioErr = MYKONOS_setTx2AttenCtrlPin(&mykDevice, 0, 0, 0, 0)) != MYKONOS_ERR_GPIO_OK) -    { -        /*** < Info: errorString will contain log error string in order to debug failure > ***/ -	    errorString = getGpioMykonosErrorMessage(mykGpioErr); -    } - -	if ((mykGpioErr = MYKONOS_setupGpio(&mykDevice)) != MYKONOS_ERR_GPIO_OK) -    { -        /*** < Info: errorString will contain log error string in order to debug failure > ***/ -	    errorString = getGpioMykonosErrorMessage(mykGpioErr); -    } - -	/*************************************************************************/ -	/*****                Mykonos Set manual gains values                *****/ -	/*************************************************************************/ -	if ((mykError = MYKONOS_setRx1ManualGain(&mykDevice, 255)) != MYKONOS_ERR_OK) -	{ -	    /*** < Info: errorString will contain log error string in order to debug failure > ***/ -	    errorString = getMykonosErrorMessage(mykError); -	} - -	if ((mykError = MYKONOS_setRx2ManualGain(&mykDevice, 255)) != MYKONOS_ERR_OK) -	{ -	    /*** < Info: errorString will contain log error string in order to debug failure > ***/ -	    errorString = getMykonosErrorMessage(mykError); -	} - -	if ((mykError = MYKONOS_setObsRxManualGain(&mykDevice, OBS_RX1_TXLO, 255)) != MYKONOS_ERR_OK) -	{ -	    /*** < Info: errorString will contain log error string in order to debug failure > ***/ -	    errorString = getMykonosErrorMessage(mykError); -	} - -	if ((mykError = MYKONOS_setObsRxManualGain(&mykDevice, OBS_RX2_TXLO, 255)) != MYKONOS_ERR_OK) -	{ -	    /*** < Info: errorString will contain log error string in order to debug failure > ***/ -	    errorString = getMykonosErrorMessage(mykError); -	} - -	if ((mykError = MYKONOS_setObsRxManualGain(&mykDevice, OBS_SNIFFER_A, 255)) != MYKONOS_ERR_OK) -	{ -	    /*** < Info: errorString will contain log error string in order to debug failure > ***/ -	    errorString = getMykonosErrorMessage(mykError); -	} - -	if ((mykError = MYKONOS_setObsRxManualGain(&mykDevice, OBS_SNIFFER_B, 255)) != MYKONOS_ERR_OK) -	{ -	    /*** < Info: errorString will contain log error string in order to debug failure > ***/ -	    errorString = getMykonosErrorMessage(mykError); -	} -	if ((mykError = MYKONOS_setObsRxManualGain(&mykDevice, OBS_SNIFFER_C, 255)) != MYKONOS_ERR_OK) -	{ -	    /*** < Info: errorString will contain log error string in order to debug failure > ***/ -	    errorString = getMykonosErrorMessage(mykError); -	} - -	/*************************************************************************/ -	/*****                Mykonos Initialize attenuations                *****/ -	/*************************************************************************/ -	if ((mykError = MYKONOS_setTx1Attenuation(&mykDevice, 0)) != MYKONOS_ERR_OK) -	{ -	    /*** < Info: errorString will contain log error string in order to debug failure > ***/ -	    errorString = getMykonosErrorMessage(mykError); -	} - -	if ((mykError = MYKONOS_setTx2Attenuation(&mykDevice, 0)) != MYKONOS_ERR_OK) -	{ -	    /*** < Info: errorString will contain log error string in order to debug failure > ***/ -	    errorString = getMykonosErrorMessage(mykError); -	} - -	/*************************************************************************/ -	/*****           Mykonos ARM Initialization Calibrations             *****/ -	/*************************************************************************/ - -    if ((mykError = MYKONOS_runInitCals(&mykDevice, (initCalMask & ~TX_LO_LEAKAGE_EXTERNAL))) != MYKONOS_ERR_OK) -	{ -		/*** < Info: errorString will contain log error string in order to debug failure > ***/ -		errorString = getMykonosErrorMessage(mykError); -	} - -	if ((mykError = MYKONOS_waitInitCals(&mykDevice, 60000, &errorFlag, &errorCode)) != MYKONOS_ERR_OK) -	{ -		/*** < Info: errorString will contain log error string in order to debug failure > ***/ -		errorString = getMykonosErrorMessage(mykError); -	} - -	if ((errorFlag != 0) || (errorCode != 0)) -	{ -		if ((mykError = MYKONOS_getInitCalStatus(&mykDevice, &initCalStatus)) != MYKONOS_ERR_OK) -		{ -			/*** < Info: errorString will contain log error string in order to debug failure > ***/ -			errorString = getMykonosErrorMessage(mykError); -		} - -		/*** < Info: abort init cals > ***/ -		if ((mykError = MYKONOS_abortInitCals(&mykDevice, &initCalsCompleted)) != MYKONOS_ERR_OK) -		{ -			/*** < Info: errorString will contain log error string in order to debug failure > ***/ -			errorString = getMykonosErrorMessage(mykError); -		} -		if (initCalsCompleted) -		{ -			/*** < Info: which calls had completed, per the mask > ***/ -		} - -		if ((mykError = MYKONOS_readArmCmdStatus(&mykDevice, &errorWord, &statusWord)) != MYKONOS_ERR_OK) -		{ -			/*** < Info: errorString will contain log error string in order to debug failure > ***/ -			errorString = getMykonosErrorMessage(mykError); -		} - -		if ((mykError = MYKONOS_readArmCmdStatusByte(&mykDevice, 2, &status)) != MYKONOS_ERR_OK) -		{ -			/*** < Info: errorString will contain log error string in order to debug why  failed > ***/ -			errorString = getMykonosErrorMessage(mykError); -		} -		if (status != 0) -		{ -			/*** < Info: Arm Mailbox Status Error errorWord > ***/ -			/*** < Info: Pending Flag per opcode statusWord, this follows the mask > ***/ -		} -	} -	else -	{ -		/*** < Info: Calibrations completed successfully  > ***/ -	} - -	/*************************************************************************/ -	/*****  Mykonos ARM Initialization External LOL Calibrations with PA *****/ -	/*************************************************************************/ -	/*** < Action: Please ensure PA is enabled operational at this time > ***/ -	if (initCalMask & TX_LO_LEAKAGE_EXTERNAL) -	{ -		if ((mykError = MYKONOS_runInitCals(&mykDevice, TX_LO_LEAKAGE_EXTERNAL)) != MYKONOS_ERR_OK) -		{ -			/*** < Info: errorString will contain log error string in order to debug failure > ***/ -			errorString = getMykonosErrorMessage(mykError); -		} -		if ((mykError = MYKONOS_waitInitCals(&mykDevice, 60000, &errorFlag, &errorCode)) != MYKONOS_ERR_OK) -		{ -			/*** < Info: errorString will contain log error string in order to debug failure > ***/ -			errorString = getMykonosErrorMessage(mykError); -		} -		if ((errorFlag != 0) || (errorCode != 0)) -		{ -			if ((mykError = MYKONOS_getInitCalStatus(&mykDevice, &initCalStatus)) != MYKONOS_ERR_OK) -			{ -				/*** < Info: errorString will contain log error string in order to debug failure > ***/ -				errorString = getMykonosErrorMessage(mykError); -			} - -			/*** < Info: abort init cals > ***/ -			if ((mykError = MYKONOS_abortInitCals(&mykDevice, &initCalsCompleted)) != MYKONOS_ERR_OK) -			{ -				/*** < Info: errorString will contain log error string in order to debug failure > ***/ -				errorString = getMykonosErrorMessage(mykError); -			} -			if (initCalsCompleted) -			{ -				/*** < Info: which calls had completed, per the mask > ***/ -			} - -			if ((mykError = MYKONOS_readArmCmdStatus(&mykDevice, &errorWord, &statusWord)) != MYKONOS_ERR_OK) -			{ -				/*** < Info: errorString will contain log error string in order to debug failure > ***/ -				errorString = getMykonosErrorMessage(mykError); -			} - -			if ((mykError = MYKONOS_readArmCmdStatusByte(&mykDevice, 2, &status)) != MYKONOS_ERR_OK) -			{ -				/*** < Info: errorString will contain log error string in order to debug failure > ***/ -				errorString = getMykonosErrorMessage(mykError); -			} -			if (status != 0) -			{ -				/*** < Info: Arm Mailbox Status Error errorWord > ***/ -				/*** < Info: Pending Flag per opcode statusWord, this follows the mask > ***/ -			} -		} -		else -		{ -			/*** < Info: Calibrations completed successfully  > ***/ -		} -	} - -	/*************************************************************************/ -	/*****             SYSTEM JESD bring up procedure                    *****/ -	/*************************************************************************/ -	/*** < Action: Make sure SYSREF is stopped/disabled > ***/ -	/*** < Action: Make sure BBIC JESD is reset and ready to recieve CGS chars> ***/ - -	if ((mykError = MYKONOS_enableSysrefToRxFramer(&mykDevice, 1)) != MYKONOS_ERR_OK) -	{ -	    /*** < Info: errorString will contain log error string in order to debug failure > ***/ -	    errorString = getMykonosErrorMessage(mykError); -	} -	/*** < Info: Mykonos is waiting for sysref in order to start -	 * transmitting CGS from the RxFramer> ***/ - -	if ((mykError = MYKONOS_enableSysrefToObsRxFramer(&mykDevice, 1)) != MYKONOS_ERR_OK) -	{ -	    /*** < Info: errorString will contain log error string in order to debug failure > ***/ -        errorString = getMykonosErrorMessage(mykError); -	} -	/*** < Info: Mykonos is waiting for sysref in order to start -	 * transmitting CGS from the ObsRxFramer> ***/ - -	/*** < User: Make sure SYSREF is stopped/disabled > ***/ -	if ((mykError = MYKONOS_enableSysrefToDeframer(&mykDevice, 0)) != MYKONOS_ERR_OK) -	{ -	    /*** < Info: errorString will contain log error string in order to debug failure > ***/ -        errorString = getMykonosErrorMessage(mykError); -	} - -	if ((mykError = MYKONOS_resetDeframer(&mykDevice)) != MYKONOS_ERR_OK) -	{ -	    /*** < Info: errorString will contain log error string in order to debug failure > ***/ -        errorString = getMykonosErrorMessage(mykError); -	} - -	/*** < User: make sure BBIC JESD framer is actively transmitting CGS> ***/ -	if ((mykError = MYKONOS_enableSysrefToDeframer(&mykDevice, 1)) != MYKONOS_ERR_OK) -	{ -	    /*** < Info: errorString will contain log error string in order to debug failure > ***/ -        errorString = getMykonosErrorMessage(mykError); -	} - -	/*************************************************************************/ -	/*****            Enable SYSREF to Mykonos and BBIC                  *****/ -	/*************************************************************************/ -	/*** < Action: Sends SYSREF Here > ***/ - -	/*** < Info: Mykonos is actively transmitting CGS from the RxFramer> ***/ - -	/*** < Info: Mykonos is actively transmitting CGS from the ObsRxFramer> ***/ - -	/*** < Action: Insert User: BBIC JESD Sync Verification Code Here > ***/ - -	/*************************************************************************/ -	/*****               Check Mykonos Framer Status                     *****/ -	/*************************************************************************/ -	if ((mykError = MYKONOS_readRxFramerStatus(&mykDevice, &framerStatus)) != MYKONOS_ERR_OK) -	{ -	    /*** < Info: errorString will contain log error string in order to debug failure > ***/ -        errorString = getMykonosErrorMessage(mykError); -	} -	if ((mykError = MYKONOS_readOrxFramerStatus(&mykDevice, &obsFramerStatus)) != MYKONOS_ERR_OK) -	{ -	    /*** < Info: errorString will contain log error string in order to debug failure > ***/ -        errorString = getMykonosErrorMessage(mykError); -	} - -	/*************************************************************************/ -	/*****               Check Mykonos Deframer Status                   *****/ -	/*************************************************************************/ -	if ((mykError = MYKONOS_readDeframerStatus(&mykDevice, &deframerStatus)) != MYKONOS_ERR_OK) -	{ -	    /*** < Info: errorString will contain log error string in order to debug failure > ***/ -        errorString = getMykonosErrorMessage(mykError); -	} - -	/*** < Action: When links have been verified, proceed > ***/ - -	/*************************************************************************/ -	/*****           Mykonos enable tracking calibrations                *****/ -	/*************************************************************************/ -	if ((mykError = MYKONOS_enableTrackingCals(&mykDevice, trackingCalMask)) != MYKONOS_ERR_OK) -	{ -	    /*** < Info: errorString will contain log error string in order to debug why enableTrackingCals failed > ***/ -        errorString = getMykonosErrorMessage(mykError); -	} - -	/*** < Info: Allow Rx1/2 QEC tracking and Tx1/2 QEC tracking to run when in the radioOn state -	     *  Tx calibrations will only run if radioOn and the obsRx path is set to OBS_INTERNAL_CALS > ***/ - -	/*** < Info: Function to turn radio on, Enables transmitters and receivers -	 * that were setup during MYKONOS_initialize() > ***/ -	if ((mykError = MYKONOS_radioOn(&mykDevice)) != MYKONOS_ERR_OK) -	{ -	    /*** < Info: errorString will contain log error string in order to debug failure > ***/ -        errorString = getMykonosErrorMessage(mykError); -	} - -	/*** < Info: Allow TxQEC to run when User: is not actively using ORx receive path > ***/ -	if ((mykError = MYKONOS_setObsRxPathSource(&mykDevice, OBS_RXOFF)) != MYKONOS_ERR_OK) -    { -	    /*** < Info: errorString will contain log error string in order to debug failure > ***/ -        errorString = getMykonosErrorMessage(mykError); -    } -	if ((mykError = MYKONOS_setObsRxPathSource(&mykDevice, OBS_INTERNALCALS)) != MYKONOS_ERR_OK) -	{ -	    /*** < Info: errorString will contain log error string in order to debug failure > ***/ -        errorString = getMykonosErrorMessage(mykError); -	} - -	return 0; -}
\ No newline at end of file diff --git a/mpm/lib/mykonos/adi_sample/headless.cpp b/mpm/lib/mykonos/adi_sample/headless.cpp deleted file mode 100644 index 93f079cc2..000000000 --- a/mpm/lib/mykonos/adi_sample/headless.cpp +++ /dev/null @@ -1,312 +0,0 @@ -/** - * \file headless.c - * - * \brief Contains example code for user integration with their application - * - * All data structures required for operation have been initialized with values which reflect - * these settings: - * - * Device Clock: - * 125MHz - * - * Profiles: - * Rx 100MHz, IQrate 125MSPS, Dec5 - * Tx 20/100MHz, IQrate 125MSPS, Dec5 - * ORX 100MHz, IQrate 125MSPS, Dec5 - * SRx 20MHz, IQrate 31.25MSPS, Dec5 - * - */ - -#include <stdlib.h> -#include <iostream> -#include "headless.h" -#include "../adi/t_mykonos.h" -#include "../adi/mykonos.h" -#include "../adi/mykonos_gpio.h" -#include "../config/mykonos_default_config.h" -//#include "mykonos_static_config.h" - -#include <functional> - -// dumb function to make the error reporting reusable within this file -void call_mykonos_api(std::function<mykonosErr_t()> f) -{ -    auto error = f(); -    if (error != MYKONOS_ERR_OK) -    { -        // TODO: make this an exception and stop normal processing -        // in the mean time, print an error and continue happily on -        std::cout << getMykonosErrorMessage(error) << std::endl; -    } -} - -int headlessinit(mykonosDevice_t *mykDevice) -{ -	uint32_t initCalMask = TX_BB_FILTER | ADC_TUNER | TIA_3DB_CORNER | DC_OFFSET | -	TX_ATTENUATION_DELAY | RX_GAIN_DELAY | FLASH_CAL | -	PATH_DELAY | TX_LO_LEAKAGE_INTERNAL | TX_QEC_INIT | -	LOOPBACK_RX_LO_DELAY | LOOPBACK_RX_RX_QEC_INIT | -	RX_LO_DELAY | RX_QEC_INIT; - -	uint32_t trackingCalMask = 	TRACK_RX1_QEC | -	TRACK_RX2_QEC | -	TRACK_TX1_QEC | -	TRACK_TX2_QEC | -	TRACK_ORX1_QEC| -	TRACK_ORX2_QEC; - -	/*** < Action: Insert System Clock(s) Initialization Code Here          > ***/ - -	/*** < Action: Insert BBIC Initialization Code Here                     > ***/ - -	/*************************************************************************/ -	/*****                Mykonos Initialization Sequence                *****/ -	/*************************************************************************/ - -    /*** < Action: Toggle RESETB pin on Mykonos device > ***/ -    call_mykonos_api(std::bind(MYKONOS_resetDevice, mykDevice)); -    call_mykonos_api(std::bind(MYKONOS_initialize, mykDevice)); - -	/*************************************************************************/ -	/*****                Mykonos CLKPLL Status Check                    *****/ -	/*************************************************************************/ - -    // change logic to timeout/wait for PLL lock -    { -        uint8_t pllLockStatus = 0; -        call_mykonos_api(std::bind(MYKONOS_checkPllsLockStatus, mykDevice, &pllLockStatus)); - -        if (pllLockStatus & 0x01) -        { -            /*** < User: code here for actions once CLKPLL locked  > ***/ -        } -        else -        { -            /*** < User: code here here for actions since CLKPLL not locked -             * ensure lock before proceeding - > ***/ -        } -    } - -    // Multichip sync was here - -	/*************************************************************************/ -	/*****                Mykonos Load ARM file                          *****/ -	/*************************************************************************/ - -    // deleted check for PLL lock here, do not advance until PLL is locked - -    call_mykonos_api(std::bind(MYKONOS_initArm, mykDevice)); -    { -        // TODO: Add code for loading ARM binary here -        uint8_t binary[98304] = { 0 }; -        uint32_t count = sizeof(binary); -        call_mykonos_api(std::bind(MYKONOS_loadArmFromBinary, mykDevice, &binary[0], count)); -    } - -	/*************************************************************************/ -	/*****                Mykonos Set RF PLL Frequencies                 *****/ -	/*************************************************************************/ - -    call_mykonos_api(std::bind(MYKONOS_setRfPllFrequency, mykDevice, RX_PLL, mykDevice->rx->rxPllLoFrequency_Hz)); -    call_mykonos_api(std::bind(MYKONOS_setRfPllFrequency, mykDevice, TX_PLL, mykDevice->tx->txPllLoFrequency_Hz)); -    call_mykonos_api(std::bind(MYKONOS_setRfPllFrequency, mykDevice, SNIFFER_PLL, mykDevice->obsRx->snifferPllLoFrequency_Hz)); - -	/*** < Action: wait 200ms for PLLs to lock > ***/ - -    // change logic to wait for rest of PLLs to lock -    { -        uint8_t pllLockStatus = 0; -        call_mykonos_api(std::bind(MYKONOS_checkPllsLockStatus, mykDevice, &pllLockStatus)); - -        if ((pllLockStatus & 0x0F) == 0x0F) -        { -            /*** < Info: All PLLs locked > ***/ -        } -        else -        { -            /*** < Info: PLLs not locked  > ***/ -            /*** < Action: Ensure lock before proceeding - User code here > ***/ -        } -    } - -    // GPIO Ctrl set up was here - -	/*************************************************************************/ -	/*****                Mykonos Set manual gains values                *****/ -	/*************************************************************************/ - -    call_mykonos_api(std::bind(MYKONOS_setRx1ManualGain, mykDevice, 255)); -    call_mykonos_api(std::bind(MYKONOS_setRx2ManualGain, mykDevice, 255)); - -    // setting gain of obs and sniffer channels was here - -	/*************************************************************************/ -	/*****                Mykonos Initialize attenuations                *****/ -	/*************************************************************************/ - -    call_mykonos_api(std::bind(MYKONOS_setTx1Attenuation, mykDevice, 0)); -    call_mykonos_api(std::bind(MYKONOS_setTx2Attenuation, mykDevice, 0)); - -	/*************************************************************************/ -	/*****           Mykonos ARM Initialization Calibrations             *****/ -	/*************************************************************************/ - -    call_mykonos_api(std::bind(MYKONOS_runInitCals, mykDevice, (initCalMask & ~TX_LO_LEAKAGE_EXTERNAL))); - -    { -        uint8_t errorFlag = 0; -        uint8_t errorCode = 0; -        call_mykonos_api(std::bind(MYKONOS_waitInitCals, mykDevice, 60000, &errorFlag, &errorCode)); - -        if ((errorFlag != 0) || (errorCode != 0)) -        { -            mykonosInitCalStatus_t initCalStatus = { 0 }; -            call_mykonos_api(std::bind(MYKONOS_getInitCalStatus, mykDevice, &initCalStatus)); - -            /*** < Info: abort init cals > ***/ -            uint32_t initCalsCompleted = 0; -            call_mykonos_api(std::bind(MYKONOS_abortInitCals, mykDevice, &initCalsCompleted)); -            if (initCalsCompleted) -            { -                /*** < Info: which calls had completed, per the mask > ***/ -            } - -            uint16_t errorWord = 0; -            uint16_t statusWord = 0; -            call_mykonos_api(std::bind(MYKONOS_readArmCmdStatus, mykDevice, &errorWord, &statusWord)); - -            uint8_t status = 0; -            call_mykonos_api(std::bind(MYKONOS_readArmCmdStatusByte, mykDevice, 2, &status)); - -            if (status != 0) -            { -                /*** < Info: Arm Mailbox Status Error errorWord > ***/ -                /*** < Info: Pending Flag per opcode statusWord, this follows the mask > ***/ -            } -        } -        else -        { -            /*** < Info: Calibrations completed successfully  > ***/ -        } -    } - -	/*************************************************************************/ -	/*****  Mykonos ARM Initialization External LOL Calibrations with PA *****/ -	/*************************************************************************/ -	/*** < Action: Please ensure PA is enabled operational at this time > ***/ -	if (initCalMask & TX_LO_LEAKAGE_EXTERNAL) -	{ -        call_mykonos_api(std::bind(MYKONOS_runInitCals, mykDevice, TX_LO_LEAKAGE_EXTERNAL)); - -        uint8_t errorFlag = 0; -        uint8_t errorCode = 0; -        call_mykonos_api(std::bind(MYKONOS_waitInitCals, mykDevice, 60000, &errorFlag, &errorCode)); - -		if ((errorFlag != 0) || (errorCode != 0)) -		{ -            mykonosInitCalStatus_t initCalStatus = { 0 }; -            call_mykonos_api(std::bind(MYKONOS_getInitCalStatus, mykDevice, &initCalStatus)); - -			/*** < Info: abort init cals > ***/ -            uint32_t initCalsCompleted = 0; -            call_mykonos_api(std::bind(MYKONOS_abortInitCals, mykDevice, &initCalsCompleted)); -			if (initCalsCompleted) -			{ -				/*** < Info: which calls had completed, per the mask > ***/ -			} - -            uint16_t errorWord = 0; -            uint16_t statusWord = 0; -            call_mykonos_api(std::bind(MYKONOS_readArmCmdStatus, mykDevice, &errorWord, &statusWord)); - -            uint8_t status = 0; -            call_mykonos_api(std::bind(MYKONOS_readArmCmdStatusByte, mykDevice, 2, &status)); -			if (status != 0) -			{ -				/*** < Info: Arm Mailbox Status Error errorWord > ***/ -				/*** < Info: Pending Flag per opcode statusWord, this follows the mask > ***/ -			} -		} -		else -		{ -			/*** < Info: Calibrations completed successfully  > ***/ -		} -	} - -	/*************************************************************************/ -	/*****             SYSTEM JESD bring up procedure                    *****/ -	/*************************************************************************/ -	/*** < Action: Make sure SYSREF is stopped/disabled > ***/ -	/*** < Action: Make sure BBIC JESD is reset and ready to recieve CGS chars> ***/ - -    call_mykonos_api(std::bind(MYKONOS_enableSysrefToRxFramer, mykDevice, 1)); - -	/*** < Info: Mykonos is waiting for sysref in order to start -	 * transmitting CGS from the RxFramer> ***/ - -    call_mykonos_api(std::bind(MYKONOS_enableSysrefToObsRxFramer, mykDevice, 1)); - -	/*** < Info: Mykonos is waiting for sysref in order to start -	 * transmitting CGS from the ObsRxFramer> ***/ - -	/*** < User: Make sure SYSREF is stopped/disabled > ***/ -    call_mykonos_api(std::bind(MYKONOS_enableSysrefToDeframer, mykDevice, 0)); - -    call_mykonos_api(std::bind(MYKONOS_resetDeframer, mykDevice)); -    call_mykonos_api(std::bind(MYKONOS_enableSysrefToDeframer, mykDevice, 1)); - -	/*** < User: make sure BBIC JESD framer is actively transmitting CGS> ***/ - -	/*************************************************************************/ -	/*****            Enable SYSREF to Mykonos and BBIC                  *****/ -	/*************************************************************************/ -	/*** < Action: Sends SYSREF Here > ***/ - -	/*** < Info: Mykonos is actively transmitting CGS from the RxFramer> ***/ - -	/*** < Info: Mykonos is actively transmitting CGS from the ObsRxFramer> ***/ - -	/*** < Action: Insert User: BBIC JESD Sync Verification Code Here > ***/ - -	/*************************************************************************/ -	/*****               Check Mykonos Framer Status                     *****/ -	/*************************************************************************/ -    { -        uint8_t framerStatus = 0; -        call_mykonos_api(std::bind(MYKONOS_readRxFramerStatus, mykDevice, &framerStatus)); -    } - -    { -        uint8_t obsFramerStatus = 0; -        call_mykonos_api(std::bind(MYKONOS_readOrxFramerStatus, mykDevice, &obsFramerStatus)); -    } - -	/*************************************************************************/ -	/*****               Check Mykonos Deframer Status                   *****/ -	/*************************************************************************/ - -    { -        uint8_t deframerStatus = 0; -        call_mykonos_api(std::bind(MYKONOS_readDeframerStatus, mykDevice, &deframerStatus)); -    } -	/*** < Action: When links have been verified, proceed > ***/ - -	/*************************************************************************/ -	/*****           Mykonos enable tracking calibrations                *****/ -	/*************************************************************************/ - -    call_mykonos_api(std::bind(MYKONOS_enableTrackingCals, mykDevice, trackingCalMask)); - -	/*** < Info: Allow Rx1/2 QEC tracking and Tx1/2 QEC tracking to run when in the radioOn state -	     *  Tx calibrations will only run if radioOn and the obsRx path is set to OBS_INTERNAL_CALS > ***/ - -	/*** < Info: Function to turn radio on, Enables transmitters and receivers -	 * that were setup during MYKONOS_initialize() > ***/ - -    call_mykonos_api(std::bind(MYKONOS_radioOn, mykDevice)); -    /*** < Info: Allow TxQEC to run when User: is not actively using ORx receive path > ***/ -    call_mykonos_api(std::bind(MYKONOS_setObsRxPathSource, mykDevice, OBS_RXOFF)); -    call_mykonos_api(std::bind(MYKONOS_setObsRxPathSource, mykDevice, OBS_INTERNALCALS)); - -	return 0; -} diff --git a/mpm/lib/mykonos/adi_sample/headless.h b/mpm/lib/mykonos/adi_sample/headless.h deleted file mode 100644 index abdfb65bf..000000000 --- a/mpm/lib/mykonos/adi_sample/headless.h +++ /dev/null @@ -1,10 +0,0 @@ -/** - * \file headless.h - * - * \brief Contains definitions for headless.c -*/ -#pragma once - -#include "mykonos_static_config.h" - -int headlessinit(mykonosDevice_t *mykDevice); diff --git a/mpm/lib/mykonos/adi_sample/mykonos_static_config.c b/mpm/lib/mykonos/adi_sample/mykonos_static_config.c deleted file mode 100644 index 1a70963aa..000000000 --- a/mpm/lib/mykonos/adi_sample/mykonos_static_config.c +++ /dev/null @@ -1,516 +0,0 @@ -/** - * \brief Contains init setting structure declarations for the _instance API - * - * The top level structure mykonosDevice_t mykDevice uses keyword - * extern to allow the application layer main() to have visibility - * to these settings. - * - * All data structures required for operation have been initialized with values which reflect these settings: - * - * Device Clock: - * 125MHz - * - * Profiles: - * Rx 100MHz, IQrate 125MSPS, Dec5 - * Tx 20/100MHz, IQrate 125MSPS, Dec5 - * ORX 100MHz, IQrate 125MSPS, Dec5 - * SRx 20MHz, IQrate 31.25MSPS, Dec5 - * - */ - -#include "mykonos_static_config.h" -#include "../adi/t_mykonos_gpio.h" -#include <stddef.h> - -static int16_t txFirCoefs[] = {-94,-26,282,177,-438,-368,756,732,-1170,-1337,1758,2479,-2648,-5088,4064,16760,16759,4110,-4881,-2247,2888,1917,-1440,-1296,745,828,-358,-474,164,298,-16,-94}; - -static mykonosFir_t txFir = -{ -    6,              /* Filter gain in dB*/ -    32,             /* Number of coefficients in the FIR filter*/ -    &txFirCoefs[0]  /* A pointer to an array of filter coefficients*/ -}; - -static int16_t rxFirCoefs[] = {-20,6,66,22,-128,-54,240,126,-402,-248,634,444,-956,-756,1400,1244,-2028,-2050,2978,3538,-4646,-7046,9536,30880,30880,9536,-7046,-4646,3538,2978,-2050,-2028,1244,1400,-756,-956,444,634,-248,-402,126,240,-54,-128,22,66,6,-20}; - -static mykonosFir_t rxFir = -{ -    -6,             /* Filter gain in dB*/ -    48,             /* Number of coefficients in the FIR filter*/ -    &rxFirCoefs[0]  /* A pointer to an array of filter coefficients*/ -}; - -static int16_t obsrxFirCoefs[] = {-14,-19,44,41,-89,-95,175,178,-303,-317,499,527,-779,-843,1184,1317,-1781,-2059,2760,3350,-4962,-7433,9822,32154,32154,9822,-7433,-4962,3350,2760,-2059,-1781,1317,1184,-843,-779,527,499,-317,-303,178,175,-95,-89,41,44,-19,-14}; -static mykonosFir_t obsrxFir = -{ -    -6,             /* Filter gain in dB*/ -    48,             /* Number of coefficients in the FIR filter*/ -    &obsrxFirCoefs[0]/* A pointer to an array of filter coefficients*/ -}; - -static int16_t snifferFirCoefs[] = {-1,-5,-14,-23,-16,24,92,137,80,-120,-378,-471,-174,507,1174,1183,98,-1771,-3216,-2641,942,7027,13533,17738,17738,13533,7027,942,-2641,-3216,-1771,98,1183,1174,507,-174,-471,-378,-120,80,137,92,24,-16,-23,-14,-5,-1}; -static mykonosFir_t snifferRxFir= -{ -    -6,             /* Filter gain in dB*/ -    48,             /* Number of coefficients in the FIR filter*/ -    &snifferFirCoefs[0]/* A pointer to an array of filter coefficients*/ -}; - -static mykonosJesd204bFramerConfig_t rxFramer = -{ -    0,              /* JESD204B Configuration Bank ID -extension to Device ID (Valid 0..15)*/ -    0,              /* JESD204B Configuration Device ID - link identification number. (Valid 0..255)*/ -    0,              /* JESD204B Configuration starting Lane ID.  If more than one lane used, each lane will increment from the Lane0 ID. (Valid 0..31)*/ -    4,              /* number of ADCs (0, 2, or 4) - 2 ADCs per receive chain*/ -    32,             /* number of frames in a multiframe (default=32), F*K must be a multiple of 4. (F=2*M/numberOfLanes)*/ -    1,              /* scrambling off if framerScramble= 0, if framerScramble>0 scramble is enabled.*/ -    1,              /* 0=use internal SYSREF, 1= use external SYSREF*/ -    0x0F,           /* serializerLanesEnabled - bit per lane, [0] = Lane0 enabled, [1] = Lane1 enabled*/ -    0xE4,           /* serializerLaneCrossbar*/ -    22,             /* serializerAmplitude - default 22 (valid (0-31)*/ -    4,              /* preEmphasis - < default 4 (valid 0 - 7)*/ -    0,              /* invertLanePolarity - default 0 ([0] will invert lane [0], bit1 will invert lane1)*/ -    0,              /* lmfcOffset - LMFC_Offset offset value for deterministic latency setting*/ -    0,              /* Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, 0 = not set*/ -    0,              /* Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set*/ -    0,              /* Selects SYNCb input source. Where, 0 = use RXSYNCB for this framer, 1 = use OBSRX_SYNCB for this framer*/ -    0,              /* Flag for determining if CMOS mode for RX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS*/ -    0               /* Selects framer bit repeat or oversampling mode for lane rate matching. Where, 0 = bitRepeat mode (changes effective lanerate), 1 = overSample (maintains same lane rate between ObsRx framer and Rx framer and oversamples the ADC samples)*/ -}; - -static mykonosJesd204bFramerConfig_t obsRxFramer = -{ -    0,              /* JESD204B Configuration Bank ID -extension to Device ID (Valid 0..15)*/ -    0,              /* JESD204B Configuration Device ID - link identification number. (Valid 0..255)*/ -    0,              /* JESD204B Configuration starting Lane ID.  If more than one lane used, each lane will increment from the Lane0 ID. (Valid 0..31)*/ -    2,              /* number of ADCs (0, 2, or 4) - 2 ADCs per receive chain*/ -    32,             /* number of frames in a multiframe (default=32), F*K must be a multiple of 4. (F=2*M/numberOfLanes)*/ -    1,              /* scrambling off if framerScramble= 0, if framerScramble>0 scramble is enabled.*/ -    1,              /* 0=use internal SYSREF, 1= use external SYSREF*/ -    0x00,           /* serializerLanesEnabled - bit per lane, [0] = Lane0 enabled, [1] = Lane1 enabled*/ -    0xE4,           /* Lane crossbar to map framer lane outputs to physical lanes*/ -    22,             /* serializerAmplitude - default 22 (valid (0-31)*/ -    4,              /* preEmphasis - < default 4 (valid 0 - 7)*/ -    0,              /* invertLanePolarity - default 0 ([0] will invert lane [0], bit1 will invert lane1)*/ -    0,              /* lmfcOffset - LMFC_Offset offset value for deterministic latency setting*/ -    0,              /* Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, 0 = not set*/ -    0,              /* Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set*/ -    1,              /* Selects SYNCb input source. Where, 0 = use RXSYNCB for this framer, 1 = use OBSRX_SYNCB for this framer*/ -    0,              /* Flag for determining if CMOS mode for RX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS*/ -    1               /* Selects framer bit repeat or oversampling mode for lane rate matching. Where, 0 = bitRepeat mode (changes effective lanerate), 1 = overSample (maintains same lane rate between ObsRx framer and Rx framer and oversamples the ADC samples)*/ -}; - -static mykonosJesd204bDeframerConfig_t deframer = -{ -    0,              /* bankId extension to Device ID (Valid 0..15)*/ -    0,              /* deviceId  link identification number. (Valid 0..255)*/ -    0,              /* lane0Id Lane0 ID. (Valid 0..31)*/ -    4,              /* M  number of DACss (0, 2, or 4) - 2 DACs per transmit chain */ -    32,             /* K  #frames in a multiframe (default=32), F*K=multiple of 4. (F=2*M/numberOfLanes)*/ -    1,              /* scramble  scrambling off if scramble= 0.*/ -    1,              /* External SYSREF select. 0 = use internal SYSREF, 1 = external SYSREF*/ -    0x0F,           /* Deserializer lane select bit field. Where, [0] = Lane0 enabled, [1] = Lane1 enabled, etc */ -    0xE4,           /* Lane crossbar to map physical lanes to deframer lane inputs [1:0] = Deframer Input 0 Lane section, [3:2] = Deframer Input 1 lane select, etc */ -    1,              /* Equalizer setting. Applied to all deserializer lanes. Range is 0..4*/ -    0,              /* PN inversion per each lane.  bit[0] = 1 Invert PN of Lane 0, bit[1] = Invert PN of Lane 1, etc).*/ -    0,              /* LMFC_Offset offset value to adjust deterministic latency. Range is 0..31*/ -    0,              /* Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, '0' = not set*/ -    0,              /* Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set*/ -    0               /* Flag for determining if CMOS mode for TX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS*/ -}; - -static mykonosRxGainControl_t rxGainControl = -{ -    MGC,            /* Current Rx gain control mode setting*/ -    255,            /* Rx1 Gain Index, can be used in different ways for manual and AGC gain control*/ -    255,            /* Rx2 Gain Index, can be used in different ways for manual and AGC gain control*/ -    255,            /* Max gain index for the currently loaded Rx1 Gain table*/ -    195,            /* Min gain index for the currently loaded Rx1 Gain table*/ -    255,            /* Max gain index for the currently loaded Rx2 Gain table*/ -    195,            /* Min gain index for the currently loaded Rx2 Gain table*/ -    0,              /* Stores Rx1 RSSI value read back from the Mykonos*/ -    0               /* Stores Rx2 RSSI value read back from the Mykonos*/ -}; - -static mykonosORxGainControl_t orxGainControl = -{ -    MGC,            /* Current ORx gain control mode setting*/ -    255,            /* ORx1 Gain Index, can be used in different ways for manual and AGC gain control*/ -    255,            /* ORx2 Gain Index, can be used in different ways for manual and AGC gain control*/ -    255,            /* Max gain index for the currently loaded ORx Gain table*/ -    237             /* Min gain index for the currently loaded ORx Gain table*/ -}; - -static mykonosSnifferGainControl_t snifferGainControl = -{ -    MGC,            /* Current Sniffer gain control mode setting*/ -    255,            /* Current Sniffer gain index. Can be used differently for MANUAL Gain control/AGC*/ -    255,            /* Max gain index for the currently loaded Sniffer Gain table*/ -    203             /* Min gain index for the currently loaded Sniffer Gain table*/ -}; - -static mykonosPeakDetAgcCfg_t rxPeakAgc = -{ -    0x00,	/* apdHighThresh: */ -    0x00,	/* apdLowThresh */ -    0x00,	/* hb2HighThresh */ -    0x00,	/* hb2LowThresh */ -    0x00,	/* hb2VeryLowThresh */ -    0x00,	/* apdHighThreshExceededCnt */ -    0x00,	/* apdLowThreshExceededCnt */ -    0x00,	/* hb2HighThreshExceededCnt */ -    0x00,	/* hb2LowThreshExceededCnt */ -    0x00,	/* hb2VeryLowThreshExceededCnt */ -    0x0,	/* apdHighGainStepAttack */ -    0x0,	/* apdLowGainStepRecovery */ -    0x0,	/* hb2HighGainStepAttack */ -    0x0,	/* hb2LowGainStepRecovery */ -    0x0,	/* hb2VeryLowGainStepRecovery */ -    0x0,	/* apdFastAttack */ -    0x0,	/* hb2FastAttack */ -    0x0,	/* hb2OverloadDetectEnable */ -    0x0,	/* hb2OverloadDurationCnt */ -    0x0	/* hb2OverloadThreshCnt */ -}; - -static mykonosPowerMeasAgcCfg_t rxPwrAgc = -{ -    0x00,	/* pmdUpperHighThresh */ -    0x00,	/* pmdUpperLowThresh */ -    0x00,	/* pmdLowerHighThresh */ -    0x00,	/* pmdLowerLowThresh */ -    0x0,	/* pmdUpperHighGainStepAttack */ -    0x0,	/* pmdUpperLowGainStepAttack */ -    0x0,	/* pmdLowerHighGainStepRecovery */ -    0x0,	/* pmdLowerLowGainStepRecovery */ -    0x00,	/* pmdMeasDuration */ -    0x00	/* pmdMeasConfig */ -}; - -static mykonosAgcCfg_t rxAgcConfig = -{ -    0,	/* agcRx1MaxGainIndex */ -    0,	/* agcRx1MinGainIndex */ -    0,	/* agcRx2MaxGainIndex */ -    0,	/* agcRx2MinGainIndex: */ -    0,	/* agcObsRxMaxGainIndex */ -    0,	/* agcObsRxMinGainIndex */ -    0,		/* agcObsRxSelect */ -    0,		/* agcPeakThresholdMode */ -    0,		/* agcLowThsPreventGainIncrease */ -    0,	/* agcGainUpdateCounter */ -    0,	/* agcSlowLoopSettlingDelay */ -    0,	/* agcPeakWaitTime */ -    0,	/* agcResetOnRxEnable */ -    0,	/* agcEnableSyncPulseForGainCounter */ -    &rxPeakAgc, -    &rxPwrAgc -}; - -static mykonosPeakDetAgcCfg_t obsRxPeakAgc = -{ -    0x00,	/* apdHighThresh: */ -    0x00,	/* apdLowThresh */ -    0x00,	/* hb2HighThresh */ -    0x00,	/* hb2LowThresh */ -    0x00,	/* hb2VeryLowThresh */ -    0x00,	/* apdHighThreshExceededCnt */ -    0x00,	/* apdLowThreshExceededCnt */ -    0x00,	/* hb2HighThreshExceededCnt */ -    0x00,	/* hb2LowThreshExceededCnt */ -    0x00,	/* hb2VeryLowThreshExceededCnt */ -    0x0,	/* apdHighGainStepAttack */ -    0x0,	/* apdLowGainStepRecovery */ -    0x0,	/* hb2HighGainStepAttack */ -    0x0,	/* hb2LowGainStepRecovery */ -    0x0,	/* hb2VeryLowGainStepRecovery */ -    0x0,	/* apdFastAttack */ -    0x0,	/* hb2FastAttack */ -    0x0,	/* hb2OverloadDetectEnable */ -    0x0,	/* hb2OverloadDurationCnt */ -    0x0		/* hb2OverloadThreshCnt */ -}; - -static mykonosPowerMeasAgcCfg_t obsRxPwrAgc = -{ -    0x00,	/* pmdUpperHighThresh */ -    0x00,	/* pmdUpperLowThresh */ -    0x00,	/* pmdLowerHighThresh */ -    0x00,	/* pmdLowerLowThresh */ -    0x0,	/* pmdUpperHighGainStepAttack */ -    0x0,	/* pmdUpperLowGainStepAttack */ -    0x0,	/* pmdLowerHighGainStepRecovery */ -    0x0,	/* pmdLowerLowGainStepRecovery */ -    0x00,	/* pmdMeasDuration */ -    0x00	/* pmdMeasConfig */ -}; - -static mykonosAgcCfg_t obsRxAgcConfig = -{ -    0,	/* agcRx1MaxGainIndex */ -    0,	/* agcRx1MinGainIndex */ -    0,	/* agcRx2MaxGainIndex */ -    0,	/* agcRx2MinGainIndex: */ -    0,	/* agcObsRxMaxGainIndex */ -    0,	/* agcObsRxMinGainIndex */ -    0,		/* agcObsRxSelect */ -    0,		/* agcPeakThresholdMode */ -    0,		/* agcLowThsPreventGainIncrease */ -    0,	/* agcGainUpdateCounter */ -    0,		/* agcSlowLoopSettlingDelay */ -    0,		/* agcPeakWaitTime */ -    0,		/* agcResetOnRxEnable */ -    0,		/* agcEnableSyncPulseForGainCounter */ -    &obsRxPeakAgc, -    &obsRxPwrAgc -}; - - -static mykonosRxProfile_t rxProfile = -{/* Rx 100MHz, IQrate 125MSPS, Dec5 */ -    1,              /* The divider used to generate the ADC clock*/ -    &rxFir,         /* Pointer to Rx FIR filter structure*/ -    2,              /* Rx FIR decimation (1,2,4)*/ -    5,              /* Decimation of Dec5 or Dec4 filter (5,4)*/ -    1,              /* If set, and DEC5 filter used, will use a higher rejection DEC5 FIR filter (1=Enabled, 0=Disabled)*/ -    1,              /* RX Half band 1 decimation (1 or 2)*/ -    125000,         /* Rx IQ data rate in kHz*/ -    100000000,      /* The Rx RF passband bandwidth for the profile*/ -    102000,         /* Rx BBF 3dB corner in kHz*/ -    NULL            /* pointer to custom ADC profile*/ -}; - -static mykonosRxProfile_t orxProfile = -{/* ORX 100MHz, IQrate 125MSPS, Dec5 */ -    1,              /* The divider used to generate the ADC clock*/ -    &obsrxFir,      /* Pointer to Rx FIR filter structure or NULL*/ -    2,              /* Rx FIR decimation (1,2,4)*/ -    5,              /* Decimation of Dec5 or Dec4 filter (5,4)*/ -    0,              /* If set, and DEC5 filter used, will use a higher rejection DEC5 FIR filter (1=Enabled, 0=Disabled)*/ -    1,              /* RX Half band 1 decimation (1 or 2)*/ -    125000,         /* Rx IQ data rate in kHz*/ -    100000000,      /* The Rx RF passband bandwidth for the profile*/ -    102000,         /* Rx BBF 3dB corner in kHz*/ -    NULL            /* pointer to custom ADC profile*/ -}; - - -static mykonosRxProfile_t snifferProfile = -{ /* SRx 20MHz, IQrate 31.25MSPS, Dec5 */ -    1,              /* The divider used to generate the ADC clock*/ -    &snifferRxFir,  /* Pointer to Rx FIR filter structure or NULL*/ -    4,              /* Rx FIR decimation (1,2,4)*/ -    5,              /* Decimation of Dec5 or Dec4 filter (5,4)*/ -    0,              /* If set, and DEC5 filter used, will use a higher rejection DEC5 FIR filter (1=Enabled, 0=Disabled)*/ -    2,              /* RX Half band 1 decimation (1 or 2)*/ -    31250,          /* Rx IQ data rate in kHz*/ -    20000000,       /* The Rx RF passband bandwidth for the profile*/ -    100000,         /* Rx BBF 3dB corner in kHz*/ -    NULL            /* pointer to custom ADC profile*/ -}; - - - -static mykonosTxProfile_t txProfile = -{ /* Tx 20/100MHz, IQrate 125MSPS, Dec5 */ -    DACDIV_2p5,     /* The divider used to generate the DAC clock*/ -    &txFir,         /* Pointer to Tx FIR filter structure*/ -    2,              /* The Tx digital FIR filter interpolation (1,2,4)*/ -    2,              /* Tx Halfband1 filter interpolation (1,2)*/ -    1,              /* Tx Halfband2 filter interpolation (1,2)*/ -    1,              /* TxInputHbInterpolation (1,2)*/ -    125000,         /* Tx IQ data rate in kHz*/ -    20000000,       /* Primary Signal BW*/ -    102000000,      /* The Tx RF passband bandwidth for the profile*/ -    722000,         /* The DAC filter 3dB corner in kHz*/ -    51000,          /* Tx BBF 3dB corner in kHz*/ -    0               /* Enable DPD, only valid for AD9373*/ -}; - -static mykonosDigClocks_t mykonosClocks = -{ -    125000,         /* CLKPLL and device reference clock frequency in kHz*/ -    10000000,       /* CLKPLL VCO frequency in kHz*/ -    VCODIV_2,       /* CLKPLL VCO divider*/ -    4               /* CLKPLL high speed clock divider*/ -}; - -static mykonosRxSettings_t  rxSettings = -{ -    &rxProfile,     /* Rx datapath profile, 3dB corner frequencies, and digital filter enables*/ -    &rxFramer,      /* Rx JESD204b framer configuration structure*/ -    &rxGainControl, /* Rx Gain control settings structure*/ -    &rxAgcConfig,   /* Rx AGC control settings structure*/ -    3,              /* The desired Rx Channels to enable during initialization*/ -    0,              /* Internal LO = 0, external LO*2 = 1*/ -    2550000000U,    /* Rx PLL LO Frequency (internal or external LO)*/ -    0               /* Flag to choose if complex baseband or real IF data are selected for Rx and ObsRx paths. Where, if > 0 = real IF data, '0' = zero IF (IQ) data*/ -}; - -static mykonosDpdConfig_t dpdConfig = -{ -    5,              /* 1/2^(damping + 8) fraction of power `forgotten' per sample (default: `1/8192' = 5, valid 0 to 15), 0 = infinite damping*/ -    1,              /* number of weights to use for int8_cpx weights weights member of this structure (default = 1)*/ -    2,              /* DPD model version: one of four different generalized polynomial models: 0 = same as R0 silicon, 1-3 are new and the best one depends on the PA (default: 2)*/ -    1,              /* 1 = Update saved model whenever peak Tx digital RMS is within 1dB of historical peak Tx RMS*/ -    20,             /* Determines how much weight the loaded prior model has on DPD modeling (Valid 0 - 32, default 20)*/ -    0,              /* Default off = 0, 1=enables automatic outlier removal during DPD modeling */ -    512,            /* Number of samples to capture (default: 512, valid 64-32768)*/ -    4096,           /* threshold for sample in AM-AM plot outside of 1:1 line to be thrown out. (default: 50% = 8192/2, valid 8192 to 1)*/ -    0,              /* 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64)*/ -    255,            /* Default 255 (-30dBFs=(20Log10(value/8192)), (valid range  1 to 8191)*/ -    {{64,0},{0,0},{0,0}}/* DPD model error weighting (real/imag valid from -128 to 127)*/ -}; - -static mykonosClgcConfig_t clgcConfig = -{ -    -2000,          /* (value = 100 * dB (valid range -32768 to 32767) - total gain and attenuation from Mykonos Tx1 output to ORx1 input in (dB * 100)*/ -    -2000,          /* (value = 100 * dB (valid range -32768 to 32767) - total gain and attenuation from Mykonos Tx2 output to ORx2 input in (dB * 100)*/ -    0,              /* (valid range 0 - 40dB), no default, depends on PA, Protects PA by making sure Tx1Atten is not reduced below the limit*/ -    0,              /* (valid range 0 - 40dB), no default, depends on PA, Protects PA by making sure Tx2Atten is not reduced below the limit*/ -    75,             /* valid range 1-100, default 75*/ -    75,             /* valid range 1-100, default 45*/ -    0,              /* 0= allow CLGC to run, but Tx1Atten will not be updated. User can still read back power measurements.  1=CLGC runs, and Tx1Atten automatically updated*/ -    0,              /* 0= allow CLGC to run, but Tx2Atten will not be updated. User can still read back power measurements.  1=CLGC runs, and Tx2Atten automatically updated*/ -    0,              /* 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64)*/ -    255             /* Default 255 (-30dBFs=(20Log10(value/8192)), (valid range  1 to 8191)*/ -}; - -static mykonosVswrConfig_t vswrConfig = -{ -    0,              /* 16th of an ORx sample (16=1sample), (default 0, valid -64 to 64)*/ -    255,            /* Default 255 (-30dBFs=(20Log10(value/8192)), (valid range  1 to 8191)*/ -    0,              /* 3p3V GPIO pin to use to control VSWR switch for Tx1 (valid 0-11) (output from Mykonos)*/ -    1,              /* 3p3V GPIO pin to use to control VSWR switch for Tx2 (valid 0-11) (output from Mykonos)*/ -    0,              /* 3p3v GPIO pin polarity for forward path of Tx1, opposite used for reflection path (1 = high level, 0 = low level)*/ -    0,              /* 3p3v GPIO pin polarity for forward path of Tx2, opposite used for reflection path (1 = high level, 0 = low level)*/ -    1,              /* Delay for Tx1 after flipping the VSWR switch until measurement is made. In ms resolution*/ -    1               /* Delay for Tx2 after flipping the VSWR switch until measurement is made. In ms resolution*/ -}; - -static mykonosTxSettings_t txSettings = -{ -    &txProfile,     /* Tx datapath profile, 3dB corner frequencies, and digital filter enables*/ -    &deframer,      /* Mykonos JESD204b deframer config for the Tx data path*/ -    TX1_TX2,        /* The desired Tx channels to enable during initialization*/ -    0,              /* Internal LO=0, external LO*2 if =1*/ -    2500000000U,    /* Tx PLL LO frequency (internal or external LO)*/ -    TXATTEN_0P05_DB,/* Initial and current Tx1 Attenuation*/ -    10000,          /* Initial and current Tx1 Attenuation mdB*/ -    10000,          /* Initial and current Tx2 Attenuation mdB*/ -    NULL,           /* DPD,CLGC,VSWR settings. Only valid for AD9373 device, set pointer to NULL otherwise*/ -    NULL,           /* CLGC Config Structure. Only valid for AD9373 device, set pointer to NULL otherwise*/ -    NULL            /* VSWR Config Structure. Only valid for AD9373 device, set pointer to NULL otherwise*/ -}; - - -static mykonosObsRxSettings_t obsRxSettings = -{ -    &orxProfile,    /* ORx datapath profile, 3dB corner frequencies, and digital filter enables*/ -    &orxGainControl,/* ObsRx gain control settings structure*/ -    &obsRxAgcConfig,/* ORx AGC control settings structure*/ -    &snifferProfile,/* Sniffer datapath profile, 3dB corner frequencies, and digital filter enables*/ -    &snifferGainControl,/* SnRx gain control settings structure*/ -    &obsRxFramer,   /* ObsRx JESD204b framer configuration structure */ -    (MYK_ORX1_ORX2 | MYK_SNRXA_B_C),/* obsRxChannel */ -    OBSLO_TX_PLL,   /* (obsRxLoSource) The Obs Rx mixer can use the Tx Synth(TX_PLL) or Sniffer Synth (SNIFFER_PLL) */ -    2600000000U,    /* SnRx PLL LO frequency in Hz */ -    0,              /* Flag to choose if complex baseband or real IF data are selected for Rx and ObsRx paths. Where if > 0 = real IF data, '0' = complex data*/ -    NULL,           /* Custom Loopback ADC profile to set the bandwidth of the ADC response */ -    OBS_RXOFF       /* Default ObsRx channel to enter when radioOn called */ -}; - -static mykonosArmGpioConfig_t armGpio = -{ -    0,	// useRx2EnablePin; /*!< 0= RX1_ENABLE controls RX1 and RX2, 1 = separate RX1_ENABLE/RX2_ENABLE pins */ -    0,	// useTx2EnablePin; /*!< 0= TX1_ENABLE controls TX1 and TX2, 1 = separate TX1_ENABLE/TX2_ENABLE pins */ -    0,	// txRxPinMode;     /*!< 0= ARM command mode, 1 = Pin mode to power up Tx/Rx chains */ -    0,	// orxPinMode;      /*!< 0= ARM command mode, 1 = Pin mode to power up ObsRx receiver*/ - -    /*Mykonos ARM input GPIO pins -- Only valid if orxPinMode = 1 */ -    0,	// orxTriggerPin; /*!< Select desired GPIO pin (valid 4-15) */ -    0,	// orxMode2Pin;   /*!< Select desired GPIO pin (valid 0-18) */ -    0,	// orxMode1Pin;   /*!< Select desired GPIO pin (valid 0-18) */ -    0,	// orxMode0Pin;   /*!< Select desired GPIO pin (valid 0-18) */ - -    /* Mykonos ARM output GPIO pins  --  always available, even when pin mode not enabled*/ -    0,	// rx1EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ -    0,	// rx2EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ -    0,	// tx1EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ -    0,	// tx2EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ -    0,	// orx1EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ -    0,	// orx2EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ -    0,	// srxEnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ -    0 	// txObsSelect;   /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ -    /* When 2Tx are used with only 1 ORx input, this GPIO tells the BBIC which Tx channel is   */ -    /* active for calibrations, so BBIC can route correct RF Tx path into the single ORx input*/ -}; - -static mykonosGpio3v3_t gpio3v3 = -{ -    0,				/*!< Oe per pin, 1=output, 0 = input */ -    GPIO3V3_BITBANG_MODE,	/*!< Mode for GPIO3V3[3:0] */ -    GPIO3V3_BITBANG_MODE,	/*!< Mode for GPIO3V3[7:4] */ -    GPIO3V3_BITBANG_MODE,	/*!< Mode for GPIO3V3[11:8] */ -}; - -static mykonosGpioLowVoltage_t gpio = -{ -    0,/* Oe per pin, 1=output, 0 = input */ -    GPIO_MONITOR_MODE,/* Mode for GPIO[3:0] */ -    GPIO_MONITOR_MODE,/* Mode for GPIO[7:4] */ -    GPIO_MONITOR_MODE,/* Mode for GPIO[11:8] */ -    GPIO_MONITOR_MODE,/* Mode for GPIO[15:12] */ -    GPIO_MONITOR_MODE,/* Mode for GPIO[18:16] */ -}; - -static mykonosAuxIo_t mykonosAuxIo = -{ -    0,	//auxDacEnableMask uint16_t -    {0,0,0,0,0,0,0,0,0,0},	 //AuxDacValue uint16[10] -    {0,0,0,0,0,0,0,0,0,0},	 //AuxDacSlope uint8[10] -    {0,0,0,0,0,0,0,0,0,0},	 //AuxDacVref uint8[10] -    &gpio3v3,	//pointer to gpio3v3 struct -    &gpio,	//pointer to gpio1v8 struct -    &armGpio -}; - -static spiSettings_t mykSpiSettings = -{ -    1, /* chip select index - valid 1~8 */ -    0, /* the level of the write bit of a SPI write instruction word, value is inverted for SPI read operation */ -    1, /* 1 = 16-bit instruction word, 0 = 8-bit instruction word */ -    1, /* 1 = MSBFirst, 0 = LSBFirst */ -    0, /* clock phase, sets which clock edge the data updates (valid 0 or 1) */ -    0, /* clock polarity 0 = clock starts low, 1 = clock starts high */ -    0, /* Not implemented in ADIs platform layer. SW feature to improve SPI throughput */ -    1, /* Not implemented in ADIs platform layer. For SPI Streaming, set address increment direction. 1= next addr = addr+1, 0:addr=addr-1 */ -    1  /* 1: Use 4-wire SPI, 0: 3-wire SPI (SDIO pin is bidirectional). NOTE: ADI's FPGA platform always uses 4-wire mode */ -}; - -static mykonosTempSensorConfig_t tempSensor = -{ -    7,              /* 3-bit value that controls the AuxADC decimation factor when used for temp sensor calculations; AuxADC_decimation = 256 * 2^tempDecimation*/ -    67,             /* 8-bit offset that gets added to temp sensor code internally*/ -    1,              /* this bit overrides the factory-calibrated fuse offset and uses the value stored in the offset member*/ -    15,             /* 4-bit code with a resolution of 1°C/LSB, each time a temperature measurement is performed, the device compares the current temperature against the previous value.*/ -}; - -static mykonosTempSensorStatus_t tempStatus = -{ -    0,              /* 16-bit signed temperature value (in deg C) that is read back*/ -    0,              /* If the absolute value of the difference is greater than the value in temperature configuration tempWindow, the windowExceeded flag is set.*/ -    0,              /* when windowExceeded member gets set, this bit is set to 1 if current value is greater than previous value, else reset*/ -    0,              /* when the reading is complete and a valid temperature value stored in tempCode.*/ -}; - -mykonosDevice_t mykDevice = -{ -    &mykSpiSettings,    /* SPI settings data structure pointer */ -    &rxSettings,        /* Rx settings data structure pointer */ -    &txSettings,        /* Tx settings data structure pointer */ -    &obsRxSettings,     /* ObsRx settings data structure pointer */ -    &mykonosAuxIo,          /* Auxiliary IO settings data structure pointer */ -    &mykonosClocks,     /* Holds settings for CLKPLL and reference clock */ -    0                   /* Mykonos initialize function uses this as an output to remember which profile data structure pointers are valid */ -}; diff --git a/mpm/lib/mykonos/adi_sample/mykonos_static_config.h b/mpm/lib/mykonos/adi_sample/mykonos_static_config.h deleted file mode 100644 index 8b919fe5b..000000000 --- a/mpm/lib/mykonos/adi_sample/mykonos_static_config.h +++ /dev/null @@ -1,18 +0,0 @@ -/** - * \file myk_init.h - * - * \brief Contains structure definitions for myk_init.c - * - * The top level structure mykonosDevice_t mykDevice uses keyword - * extern to allow the application layer main() to have visibility - * to these settings. - */ - -#ifndef MYK_INIT_H_ -#define MYK_INIT_H_ - -#include "../adi/t_mykonos.h" - -extern mykonosDevice_t mykDevice; - -#endif diff --git a/mpm/lib/mykonos/config/ad937x_config_t.cpp b/mpm/lib/mykonos/config/ad937x_config_t.cpp index 5cfe6351e..23d32a558 100644 --- a/mpm/lib/mykonos/config/ad937x_config_t.cpp +++ b/mpm/lib/mykonos/config/ad937x_config_t.cpp @@ -1,8 +1,27 @@ -#include "ad937x_config_t.h" -#include "mykonos_default_config.h" - -ad937x_config_t::ad937x_config_t() +// +// 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 "ad937x_config_t.hpp" +#include "ad937x_default_config.hpp" + +ad937x_config_t::ad937x_config_t(spiSettings_t* sps)      { +    _device.spiSettings = sps; +      _assign_default_configuration();      _init_pointers();  } @@ -59,33 +78,38 @@ void ad937x_config_t::_init_pointers()      _device.clocks = &_clocks;      _rx.rxProfile = &_rxProfile; -    _rxProfile.rxFir = _rx_fir_config.getFir();      _rx.framer = &_framer;      _rx.rxGainCtrl = &_rxGainCtrl;      _rx.rxAgcCtrl = &_rxAgcCtrl; +    _rxProfile.rxFir = rx_fir_config.fir; +    _rxProfile.customAdcProfile = nullptr;      _rxAgcCtrl.peakAgc = &_rxPeakAgc;      _rxAgcCtrl.powerAgc = &_rxPowerAgc;      _tx.txProfile = &_txProfile; -    _txProfile.txFir = _tx_fir_config.getFir(); +    _txProfile.txFir = tx_fir_config.fir;      _tx.deframer = &_deframer;      // AD9373 -    //_tx.dpdConfig = &_dpdConfig; -    //_tx.clgcConfig = &_clgcConfig; -    //_tx.vswrConfig = &_vswrConfig; +    _tx.dpdConfig = nullptr; +    _tx.clgcConfig = nullptr; +    _tx.vswrConfig = nullptr; +    // TODO: ideally we set none of this information and leave the profile as nullptr +    // Check that the API supports this      _obsRx.orxProfile = &_orxProfile; -    _orxProfile.rxFir = _orx_fir_config.getFir();      _obsRx.orxGainCtrl = &_orxGainCtrl;      _obsRx.orxAgcCtrl = &_orxAgcCtrl; +    _orxProfile.rxFir = _orx_fir_config.fir; +    _orxProfile.customAdcProfile = nullptr;      _orxAgcCtrl.peakAgc = &_orxPeakAgc;      _orxAgcCtrl.powerAgc = &_orxPowerAgc;      _obsRx.snifferProfile = &_snifferProfile; -    _snifferProfile.rxFir = _sniffer_rx_fir_config.getFir(); +    _snifferProfile.rxFir = _sniffer_rx_fir_config.fir;      _obsRx.snifferGainCtrl = &_snifferGainCtrl;      // sniffer has no AGC ctrl, so leave as null +    _obsRx.orxAgcCtrl = nullptr;      _obsRx.framer = &_orxFramer;      _auxIo.gpio3v3 = &_gpio3v3; @@ -95,16 +119,10 @@ void ad937x_config_t::_init_pointers()  void ad937x_config_t::_assign_firs()  { -    // TODO: In general, storing just these pointers could lead to Bad Stuff -    // Consider if it would be helpful to enforce some pointer safety here -    // (if that's even possible with the C API) -    _rx_fir_config = { -6,{ 48, 0 } }; -    _rxProfile.rxFir = _rx_fir_config.getFir(); -    _tx_fir_config = { 6,{ 32, 0 } }; -    _txProfile.txFir = _tx_fir_config.getFir(); -    _orx_fir_config = { -6, { 48, 0 } }; -    _orxProfile.rxFir = _orx_fir_config.getFir(); -    _sniffer_rx_fir_config = { -6, { 48, 0 } }; -    _snifferProfile.rxFir = _sniffer_rx_fir_config.getFir(); +    // TODO: get default filters here +    tx_fir_config.set_fir(6, { 32, 0 }); +    rx_fir_config.set_fir( -6,{ 48, 0 }); +    _orx_fir_config.set_fir( -6, { 48, 0 }); +    _sniffer_rx_fir_config.set_fir( -6, { 48, 0 });  } diff --git a/mpm/lib/mykonos/config/ad937x_config_t.hpp b/mpm/lib/mykonos/config/ad937x_config_t.hpp index 5375e0867..1d8072244 100644 --- a/mpm/lib/mykonos/config/ad937x_config_t.hpp +++ b/mpm/lib/mykonos/config/ad937x_config_t.hpp @@ -1,21 +1,43 @@ +// +// 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/>. +// +  #pragma once  #include "../adi/t_mykonos.h" -#include "ad937x_fir.h" +#include "ad937x_fir.hpp"  #include <boost/noncopyable.hpp>  // This class exists so that the entire mykonos config can be allocated and managed together -class ad937x_device  : public boost::noncopyable +class ad937x_config_t  : public boost::noncopyable  {      // The top level device struct contains all other structs, so everything is technically "public"      // a user could technically modify the pointers in the structs, but we have no way of preventing that  public: -    ad937x_device(); +    ad937x_config_t(spiSettings_t* sps);      mykonosDevice_t * const device = &_device; +    ad937x_fir rx_fir_config; +    ad937x_fir tx_fir_config;  private:      mykonosDevice_t _device; +    ad937x_fir _orx_fir_config; +    ad937x_fir _sniffer_rx_fir_config; +      // in general, this organization stinks      // TODO: group and make more sense of these fields and pointers      spiSettings_t _spiSettings; @@ -24,35 +46,26 @@ private:      mykonosObsRxSettings_t _obsRx;      mykonosAuxIo_t _auxIo;      mykonosDigClocks_t _clocks; - -    ad937x_fir _rx_fir_config; +          mykonosRxProfile_t _rxProfile; -    std::vector<uint16_t> _customRxAdcProfile;      mykonosJesd204bFramerConfig_t _framer;      mykonosRxGainControl_t _rxGainCtrl;      mykonosAgcCfg_t _rxAgcCtrl;      mykonosPeakDetAgcCfg_t _rxPeakAgc;      mykonosPowerMeasAgcCfg_t _rxPowerAgc; - -    ad937x_fir _tx_fir_config; +          mykonosTxProfile_t _txProfile;      mykonosJesd204bDeframerConfig_t _deframer; -    mykonosDpdConfig_t _dpdConfig; -    mykonosClgcConfig_t _clgcConfig; -    mykonosVswrConfig_t _vswrConfig; - -    ad937x_fir _orx_fir_config; +          mykonosRxProfile_t _orxProfile;      mykonosORxGainControl_t _orxGainCtrl;      mykonosAgcCfg_t _orxAgcCtrl;      mykonosPeakDetAgcCfg_t _orxPeakAgc;      mykonosPowerMeasAgcCfg_t _orxPowerAgc; - -    ad937x_fir _sniffer_rx_fir_config; +          mykonosRxProfile_t _snifferProfile;      mykonosSnifferGainControl_t _snifferGainCtrl;      mykonosJesd204bFramerConfig_t _orxFramer; -    std::vector<uint16_t> _customORxAdcProfile;      mykonosGpio3v3_t _gpio3v3;      mykonosGpioLowVoltage_t _gpio; diff --git a/mpm/lib/mykonos/config/ad937x_default_config.hpp b/mpm/lib/mykonos/config/ad937x_default_config.hpp new file mode 100644 index 000000000..6cdbeacfe --- /dev/null +++ b/mpm/lib/mykonos/config/ad937x_default_config.hpp @@ -0,0 +1,376 @@ +// +// 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 "../adi/t_mykonos.h" + +// This file is more or less the static config provided by a run of the eval software +// except all pointers have been changed to nullptr +// Hopefully this helps the compiler use these as purely constants +// The pointers should be filled in if these data structures are to be actually used with the API + +static const mykonosRxSettings_t DEFAULT_RX_SETTINGS = +{ +    nullptr,        // Rx datapath profile, 3dB corner frequencies, and digital filter enables +    nullptr,        // Rx JESD204b framer configuration structure +    nullptr,        // Rx Gain control settings structure +    nullptr,        // Rx AGC control settings structure +    RX1_RX2,        // The desired Rx Channels to enable during initialization +    0,              // Internal LO = 0, external LO*2 = 1 +    3500000000U,    // Rx PLL LO Frequency (internal or external LO) +    0               // Flag to choose if complex baseband or real IF data are selected for Rx and ObsRx paths. Where, if > 0 = real IF data, '0' = zero IF (IQ) data +}; + +static const mykonosRxProfile_t DEFAULT_RX_PROFILE = +{                   // Rx 100MHz, IQrate 122.88MHz, Dec5  +    1,              // The divider used to generate the ADC clock +    nullptr,        // Pointer to Rx FIR filter structure +    2,              // Rx FIR decimation (1,2,4) +    5,              // Decimation of Dec5 or Dec4 filter (5,4) +    1,              // If set, and DEC5 filter used, will use a higher rejection DEC5 FIR filter (1=Enabled, 0=Disabled) +    1,              // RX Half band 1 decimation (1 or 2) +    122880,         // Rx IQ data rate in kHz +    100000000,      // The Rx RF passband bandwidth for the profile +    100000,         // Rx BBF 3dB corner in kHz +    NULL            // pointer to custom ADC profile +}; + +static const mykonosJesd204bFramerConfig_t DEFAULT_FRAMER = +{ +    0,              // JESD204B Configuration Bank ID -extension to Device ID (Valid 0..15) +    0,              // JESD204B Configuration Device ID - link identification number. (Valid 0..255) +    0,              // JESD204B Configuration starting Lane ID.  If more than one lane used, each lane will increment from the Lane0 ID. (Valid 0..31) +    4,              // number of ADCs (0, 2, or 4) - 2 ADCs per receive chain +    32,             // number of frames in a multiframe (default=32), F*K must be a multiple of 4. (F=2*M/numberOfLanes) +    1,              // scrambling off if framerScramble= 0, if framerScramble>0 scramble is enabled. +    1,              // 0=use internal SYSREF, 1= use external SYSREF +    0x0F,           // serializerLanesEnabled - bit per lane, [0] = Lane0 enabled, [1] = Lane1 enabled +    0xE4,           // serializerLaneCrossbar +    26,             // serializerAmplitude - default 22 (valid (0-31) +    0,              // preEmphasis - < default 4 (valid 0 - 7) +    0,              // invertLanePolarity - default 0 ([0] will invert lane [0], bit1 will invert lane1) +    0,              // lmfcOffset - LMFC offset value for deterministic latency setting +    0,              // Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, 0 = not set +    0,              // Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set +    0,              // Selects SYNCb input source. Where, 0 = use RXSYNCB for this framer, 1 = use OBSRX_SYNCB for this framer +    0,              // Flag for determining if CMOS mode for RX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS +    0               // Selects framer bit repeat or oversampling mode for lane rate matching. Where, 0 = bitRepeat mode (changes effective lanerate), 1 = overSample (maintains same lane rate between ObsRx framer and Rx framer and oversamples the ADC samples) +}; + +static const mykonosRxGainControl_t DEFAULT_RX_GAIN = +{ +    MGC,            // Current Rx gain control mode setting +    255,            // Rx1 Gain Index, can be used in different ways for manual and AGC gain control +    255,            // Rx2 Gain Index, can be used in different ways for manual and AGC gain control +    255,            // Max gain index for the currently loaded Rx1 Gain table +    195,            // Min gain index for the currently loaded Rx1 Gain table +    255,            // Max gain index for the currently loaded Rx2 Gain table +    195,            // Min gain index for the currently loaded Rx2 Gain table +    0,              // Stores Rx1 RSSI value read back from the Mykonos +    0               // Stores Rx2 RSSI value read back from the Mykonos +}; + +static const mykonosPeakDetAgcCfg_t DEFAULT_RX_PEAK_AGC = +{ +    0x1F,   // apdHighThresh:  +    0x16,   // apdLowThresh  +    0xB5,   // hb2HighThresh  +    0x80,   // hb2LowThresh  +    0x40,   // hb2VeryLowThresh  +    0x06,   // apdHighThreshExceededCnt  +    0x04,   // apdLowThreshExceededCnt  +    0x06,   // hb2HighThreshExceededCnt  +    0x04,   // hb2LowThreshExceededCnt  +    0x04,   // hb2VeryLowThreshExceededCnt  +    0x4,    // apdHighGainStepAttack  +    0x2,    // apdLowGainStepRecovery  +    0x4,    // hb2HighGainStepAttack  +    0x2,    // hb2LowGainStepRecovery  +    0x4,    // hb2VeryLowGainStepRecovery  +    0x1,    // apdFastAttack  +    0x1,    // hb2FastAttack  +    0x1,    // hb2OverloadDetectEnable  +    0x1,    // hb2OverloadDurationCnt  +    0x1     // hb2OverloadThreshCnt  +}; + +static const mykonosPowerMeasAgcCfg_t DEFAULT_RX_POWER_AGC = +{ +    0x01,   // pmdUpperHighThresh  +    0x03,   // pmdUpperLowThresh  +    0x0C,   // pmdLowerHighThresh  +    0x04,   // pmdLowerLowThresh  +    0x4,    // pmdUpperHighGainStepAttack  +    0x2,    // pmdUpperLowGainStepAttack  +    0x2,    // pmdLowerHighGainStepRecovery  +    0x4,    // pmdLowerLowGainStepRecovery  +    0x08,   // pmdMeasDuration  +    0x02    // pmdMeasConfig  +}; + +static const mykonosAgcCfg_t DEFAULT_RX_AGC_CTRL = +{ +    255,    // AGC peak wait time  +    195,    // agcRx1MinGainIndex  +    255,    // agcRx2MaxGainIndex  +    195,    // agcRx2MinGainIndex:  +    255,    // agcObsRxMaxGainIndex  +    203,    // agcObsRxMinGainIndex  +    1,      // agcObsRxSelect  +    1,      // agcPeakThresholdMode  +    1,      // agcLowThsPreventGainIncrease  +    30720,  // agcGainUpdateCounter  +    3,      // agcSlowLoopSettlingDelay  +    2,      // agcPeakWaitTime  +    0,      // agcResetOnRxEnable  +    0,      // agcEnableSyncPulseForGainCounter  +    nullptr,// *peakAgc +    nullptr // *powerAgc +}; + +static const mykonosTxSettings_t DEFAULT_TX_SETTINGS = +{ +    nullptr,        // Tx datapath profile, 3dB corner frequencies, and digital filter enables +    nullptr,        // Mykonos JESD204b deframer config for the Tx data path +    TX1_TX2,        // The desired Tx channels to enable during initialization +    0,              // Internal LO=0, external LO*2 if =1 +    3500000000U,    // Tx PLL LO frequency (internal or external LO) +    TXATTEN_0P05_DB,// Initial and current Tx1 Attenuation +    10000,          // Initial and current Tx1 Attenuation mdB +    10000,          // Initial and current Tx2 Attenuation mdB +    nullptr,        // DPD,CLGC,VSWR settings. Only valid for AD9373 device, set pointer to NULL otherwise +    nullptr,        // CLGC Config Structure. Only valid for AD9373 device, set pointer to NULL otherwise +    nullptr         // VSWR Config Structure. Only valid for AD9373 device, set pointer to NULL otherwise +}; + +static const mykonosTxProfile_t DEFAULT_TX_PROFILE = +{                   // Tx 20/100MHz, IQrate 122.88MHz, Dec5  +    DACDIV_2p5,     // The divider used to generate the DAC clock +    nullptr,        // Pointer to Tx FIR filter structure +    2,              // The Tx digital FIR filter interpolation (1,2,4) +    2,              // Tx Halfband1 filter interpolation (1,2) +    1,              // Tx Halfband2 filter interpolation (1,2) +    1,              // TxInputHbInterpolation (1,2) +    122880,         // Tx IQ data rate in kHz +    20000000,       // Primary Signal BW +    100000000,      // The Tx RF passband bandwidth for the profile +    710539,         // The DAC filter 3dB corner in kHz +    50000,          // Tx BBF 3dB corner in kHz +    0               // Enable DPD, only valid for AD9373 +}; + +static const mykonosJesd204bDeframerConfig_t DEFAULT_DEFRAMER = +{ +    0,              // bankId extension to Device ID (Valid 0..15) +    0,              // deviceId  link identification number. (Valid 0..255) +    0,              // lane0Id Lane0 ID. (Valid 0..31) +    4,              // M  number of DACss (0, 2, or 4) - 2 DACs per transmit chain  +    32,             // K  #frames in a multiframe (default=32), F*K=multiple of 4. (F=2*M/numberOfLanes) +    0,              // Scrambling off if scramble = 0, if framerScramble > 0 scrambling is enabled +    1,              // External SYSREF select. 0 = use internal SYSREF, 1 = external SYSREF +    0x0F,           // Deserializer lane select bit field. Where, [0] = Lane0 enabled, [1] = Lane1 enabled, etc  +    0xE4,           // Lane crossbar to map physical lanes to deframer lane inputs [1:0] = Deframer Input 0 Lane section, [3:2] = Deframer Input 1 lane select, etc  +    1,              // Equalizer setting. Applied to all deserializer lanes. Range is 0..4 +    0,              // PN inversion per each lane.  bit[0] = 1 Invert PN of Lane 0, bit[1] = Invert PN of Lane 1, etc). +    0,              // LMFC offset value to adjust deterministic latency. Range is 0..31 +    0,              // Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, '0' = not set +    0,              // Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set +    0               // Flag for determining if CMOS mode for TX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS +}; + +static const mykonosObsRxSettings_t DEFAULT_ORX_SETTINGS = +{ +    nullptr,        // ORx datapath profile, 3dB corner frequencies, and digital filter enables +    nullptr,        // ObsRx gain control settings structure +    nullptr,        // ORx AGC control settings structure +    nullptr,        // Sniffer datapath profile, 3dB corner frequencies, and digital filter enables +    nullptr,        // SnRx gain control settings structure +    nullptr,        // ObsRx JESD204b framer configuration structure  +    MYK_OBS_RXOFF,  // obsRxChannel  +    OBSLO_TX_PLL,   // (obsRxLoSource) The Obs Rx mixer can use the Tx Synth(TX_PLL) or Sniffer Synth (SNIFFER_PLL)  +    2600000000U,    // SnRx PLL LO frequency in Hz  +    0,              // Flag to choose if complex baseband or real IF data are selected for Rx and ObsRx paths. Where if > 0 = real IF data, '0' = complex data +    nullptr,        // Custom Loopback ADC profile to set the bandwidth of the ADC response  +    OBS_RXOFF       // Default ObsRx channel to enter when radioOn called  +}; + +static const mykonosJesd204bFramerConfig_t DEFAULT_ORX_FRAMER = +{ +    0,              // JESD204B Configuration Bank ID -extension to Device ID (Valid 0..15) +    0,              // JESD204B Configuration Device ID - link identification number. (Valid 0..255) +    0,              // JESD204B Configuration starting Lane ID.  If more than one lane used, each lane will increment from the Lane0 ID. (Valid 0..31) +    2,              // number of ADCs (0, 2, or 4) - 2 ADCs per receive chain +    32,             // number of frames in a multiframe (default=32), F*K must be a multiple of 4. (F=2*M/numberOfLanes) +    1,              // scrambling off if framerScramble= 0, if framerScramble>0 scramble is enabled. +    1,              // 0=use internal SYSREF, 1= use external SYSREF +    0x00,           // serializerLanesEnabled - bit per lane, [0] = Lane0 enabled, [1] = Lane1 enabled +    0xE4,           // Lane crossbar to map framer lane outputs to physical lanes +    22,             // serializerAmplitude - default 22 (valid (0-31) +    4,              // preEmphasis - < default 4 (valid 0 - 7) +    0,              // invertLanePolarity - default 0 ([0] will invert lane [0], bit1 will invert lane1) +    0,              // lmfcOffset - LMFC_Offset offset value for deterministic latency setting +    0,              // Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, 0 = not set +    0,              // Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set +    1,              // Selects SYNCb input source. Where, 0 = use RXSYNCB for this framer, 1 = use OBSRX_SYNCB for this framer +    0,              // Flag for determining if CMOS mode for RX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS +    1               // Selects framer bit repeat or oversampling mode for lane rate matching. Where, 0 = bitRepeat mode (changes effective lanerate), 1 = overSample (maintains same lane rate between ObsRx framer and Rx framer and oversamples the ADC samples) +}; + +static const mykonosORxGainControl_t DEFAULT_ORX_GAIN = +{ +    MGC,            // Current ORx gain control mode setting +    255,            // ORx1 Gain Index, can be used in different ways for manual and AGC gain control +    255,            // ORx2 Gain Index, can be used in different ways for manual and AGC gain control +    255,            // Max gain index for the currently loaded ORx Gain table +    237             // Min gain index for the currently loaded ORx Gain table +}; + +static const mykonosAgcCfg_t DEFAULT_ORX_AGC_CTRL = +{ +    0,      // agcRx1MaxGainIndex  +    0,      // agcRx1MinGainIndex  +    0,      // agcRx2MaxGainIndex  +    0,      // agcRx2MinGainIndex:  +    0,      // agcObsRxMaxGainIndex  +    0,      // agcObsRxMinGainIndex  +    0,      // agcObsRxSelect  +    0,      // agcPeakThresholdMode  +    0,      // agcLowThsPreventGainIncrease  +    0,      // agcGainUpdateCounter  +    0,      // agcSlowLoopSettlingDelay  +    0,      // agcPeakWaitTime  +    0,      // agcResetOnRxEnable  +    0,      // agcEnableSyncPulseForGainCounter  +    nullptr,// *peakAgc +    nullptr // *powerAgc +}; + +static const mykonosPeakDetAgcCfg_t DEFAULT_ORX_PEAK_AGC = +{ +    0,      // apdHighThresh:  +    0,      // apdLowThresh  +    0,      // hb2HighThresh  +    0,      // hb2LowThresh  +    0,      // hb2VeryLowThresh  +    0,      // apdHighThreshExceededCnt  +    0,      // apdLowThreshExceededCnt  +    0,      // hb2HighThreshExceededCnt  +    0,      // hb2LowThreshExceededCnt  +    0,      // hb2VeryLowThreshExceededCnt  +    0,      // apdHighGainStepAttack  +    0,      // apdLowGainStepRecovery  +    0,      // hb2HighGainStepAttack  +    0,      // hb2LowGainStepRecovery  +    0,      // hb2VeryLowGainStepRecovery  +    0,      // apdFastAttack  +    0,      // hb2FastAttack  +    0,      // hb2OverloadDetectEnable  +    0,      // hb2OverloadDurationCnt  +    0       // hb2OverloadThreshCnt  +}; + +static const mykonosPowerMeasAgcCfg_t DEFAULT_ORX_POWER_AGC = +{ +    0,      // pmdUpperHighThresh  +    0,      // pmdUpperLowThresh  +    0,      // pmdLowerHighThresh  +    0,      // pmdLowerLowThresh  +    0,      // pmdUpperHighGainStepAttack  +    0,      // pmdUpperLowGainStepAttack  +    0,      // pmdLowerHighGainStepRecovery  +    0,      // pmdLowerLowGainStepRecovery  +    0,      // pmdMeasDuration  +    0,      // pmdMeasConfig  +}; + +static const mykonosRxProfile_t DEFAULT_ORX_PROFILE = +{// ORX 100MHz, IQrate 125MSPS, Dec5  +    1,              // The divider used to generate the ADC clock +    nullptr,        // Pointer to Rx FIR filter structure or NULL +    2,              // Rx FIR decimation (1,2,4) +    5,              // Decimation of Dec5 or Dec4 filter (5,4) +    0,              // If set, and DEC5 filter used, will use a higher rejection DEC5 FIR filter (1=Enabled, 0=Disabled) +    1,              // RX Half band 1 decimation (1 or 2) +    125000,         // Rx IQ data rate in kHz +    100000000,      // The Rx RF passband bandwidth for the profile +    102000,         // Rx BBF 3dB corner in kHz +    nullptr         // pointer to custom ADC profile +}; + +static const mykonosArmGpioConfig_t DEFAULT_ARM_GPIO = +{ +    0,  // useRx2EnablePin; //!< 0= RX1_ENABLE controls RX1 and RX2, 1 = separate RX1_ENABLE/RX2_ENABLE pins  +    0,  // useTx2EnablePin; //!< 0= TX1_ENABLE controls TX1 and TX2, 1 = separate TX1_ENABLE/TX2_ENABLE pins  +    0,  // txRxPinMode;     //!< 0= ARM command mode, 1 = Pin mode to power up Tx/Rx chains  +    0,  // orxPinMode;      //!< 0= ARM command mode, 1 = Pin mode to power up ObsRx receiver + +    //Mykonos ARM input GPIO pins -- Only valid if orxPinMode = 1  +    0,  // orxTriggerPin; //!< Select desired GPIO pin (valid 4-15)  +    0,  // orxMode2Pin;   //!< Select desired GPIO pin (valid 0-18)  +    0,  // orxMode1Pin;   //!< Select desired GPIO pin (valid 0-18)  +    0,  // orxMode0Pin;   //!< Select desired GPIO pin (valid 0-18)  + +    // Mykonos ARM output GPIO pins  --  always available, even when pin mode not enabled +    0,  // rx1EnableAck;  //!< Select desired GPIO pin (0-15), [4] = Output Enable  +    0,  // rx2EnableAck;  //!< Select desired GPIO pin (0-15), [4] = Output Enable  +    0,  // tx1EnableAck;  //!< Select desired GPIO pin (0-15), [4] = Output Enable  +    0,  // tx2EnableAck;  //!< Select desired GPIO pin (0-15), [4] = Output Enable  +    0,  // orx1EnableAck;  //!< Select desired GPIO pin (0-15), [4] = Output Enable  +    0,  // orx2EnableAck;  //!< Select desired GPIO pin (0-15), [4] = Output Enable  +    0,  // srxEnableAck;  //!< Select desired GPIO pin (0-15), [4] = Output Enable  +    0   // txObsSelect;   //!< Select desired GPIO pin (0-15), [4] = Output Enable  +        // When 2Tx are used with only 1 ORx input, this GPIO tells the BBIC which Tx channel is    +        // active for calibrations, so BBIC can route correct RF Tx path into the single ORx input +}; + +static const mykonosGpio3v3_t DEFAULT_GPIO_3V3 = +{ +    0,                      //!< Oe per pin, 1=output, 0 = input  +    GPIO3V3_BITBANG_MODE,   //!< Mode for GPIO3V3[3:0]  +    GPIO3V3_BITBANG_MODE,   //!< Mode for GPIO3V3[7:4]  +    GPIO3V3_BITBANG_MODE,   //!< Mode for GPIO3V3[11:8]  +}; + +static const mykonosGpioLowVoltage_t DEFAULT_GPIO = +{ +    0,                      // Oe per pin, 1=output, 0 = input  +    GPIO_MONITOR_MODE,      // Mode for GPIO[3:0]  +    GPIO_MONITOR_MODE,      // Mode for GPIO[7:4]  +    GPIO_MONITOR_MODE,      // Mode for GPIO[11:8]  +    GPIO_MONITOR_MODE,      // Mode for GPIO[15:12]  +    GPIO_MONITOR_MODE,      // Mode for GPIO[18:16]  +}; + +static const mykonosAuxIo_t DEFAULT_AUX_IO = +{ +    0,                          // auxDacEnable uint16_t +    { 0,0,0,0,0,0,0,0,0,0 },    // auxDacValue uint16[10] +    { 0,0,0,0,0,0,0,0,0,0 },    // auxDacSlope uint8[10] +    { 0,0,0,0,0,0,0,0,0,0 },    // auxDacVref uint8[10] +    nullptr,                    // *mykonosGpio3v3_t +    nullptr,                    // *mykonosGpioLowVoltage_t +    nullptr                     // *mykonosArmGpioConfig_t +}; + +static const mykonosDigClocks_t DEFAULT_CLOCKS = +{ +    122880,         // CLKPLL and device reference clock frequency in kHz +    9830400,        // CLKPLL VCO frequency in kHz +    VCODIV_2,       // CLKPLL VCO divider +    4               // CLKPLL high speed clock divider +}; + + diff --git a/mpm/lib/mykonos/config/ad937x_fir.cpp b/mpm/lib/mykonos/config/ad937x_fir.cpp index a9ede3318..b62227163 100644 --- a/mpm/lib/mykonos/config/ad937x_fir.cpp +++ b/mpm/lib/mykonos/config/ad937x_fir.cpp @@ -1,37 +1,51 @@ -#include "ad937x_fir.h" -#include <limits> +// +// 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/>. +// -ad937x_fir::ad937x_fir(int8_t gain, const std::vector<int16_t>& coefficients) -{ -    -    _set_gain(gain); -} +#include "ad937x_fir.hpp" -ad937x_fir::ad937x_fir(int8_t gain, std::vector<int16_t>&& coefficients) +ad937x_fir::ad937x_fir() : +    ad937x_fir(0, { 1, 0 })  { -    set_coefficients(std::move(coefficients)); -    _set_gain(gain); -} -mykonosFir_t* ad937x_fir::getFir() -{ -    return &(_fir);  } -void ad937x_fir::set_coefficients(std::vector<int16_t>&& coefficients) +ad937x_fir::ad937x_fir(int8_t gain, const std::vector<int16_t>& coefficients) : +    // These two constructors will be run in the order they are declared in the class definition +    // see C++ standard 12.6.2 section 13.3 +    _fir_coefficients(coefficients), +    _fir({gain,  +        static_cast<uint8_t>(_fir_coefficients.size()),  +        _fir_coefficients.data()})  { -    if (coefficients.size() < std::numeric_limits<decltype(mykonosFir_t().numFirCoefs)>::max() || -        coefficients.size() > 0) -    { -        // TODO: exception -    } -    fir_coefficients = std::move(coefficients); -    _fir.numFirCoefs = static_cast<uint8_t>(fir_coefficients.size()); -    _fir.coefs = &fir_coefficients[0]; +  } -void ad937x_fir::_set_gain(int8_t gain) +// ad937x_fir.fir should not be accessed during this operation +void ad937x_fir::set_fir(int8_t gain, const std::vector<int16_t>& coefficients)  {      _fir.gain_dB = gain; + +    _fir_coefficients = coefficients; +    _fir.coefs = _fir_coefficients.data(); +    _fir.numFirCoefs = static_cast<uint8_t>(_fir_coefficients.size());  } +std::vector<int16_t> ad937x_fir::get_fir(int8_t &gain) +{ +    gain = _fir.gain_dB; +    return _fir_coefficients; +} diff --git a/mpm/lib/mykonos/config/ad937x_fir.h b/mpm/lib/mykonos/config/ad937x_fir.h deleted file mode 100644 index ff277ef26..000000000 --- a/mpm/lib/mykonos/config/ad937x_fir.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include <vector> -#include "../adi/t_mykonos.h" - -// wraps FIR allocation -class ad937x_fir -{ -    // these should be const, but can't be because of C API -    //  -    mykonosFir_t _fir; -    std::vector<int16_t> fir_coefficients; - -    void ad937x_fir::_set_gain(int8_t gain); -public: -    ad937x_fir(int8_t gain, const std::vector<int16_t>& coefficients); -    ad937x_fir(int8_t gain, std::vector<int16_t>&& coefficients); - -    mykonosFir_t* getFir(); -}; - - diff --git a/mpm/lib/mykonos/config/ad937x_fir.hpp b/mpm/lib/mykonos/config/ad937x_fir.hpp new file mode 100644 index 000000000..f243f0f47 --- /dev/null +++ b/mpm/lib/mykonos/config/ad937x_fir.hpp @@ -0,0 +1,35 @@ +// +// 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/>. +// + +#pragma once + +#include "../adi/t_mykonos.h" +#include <vector> + +// wraps FIR allocation and provides a fixed mykonosFir_t pointer +class ad937x_fir +{ +    std::vector<int16_t> _fir_coefficients; +    mykonosFir_t _fir; +public: +    mykonosFir_t* const fir = &_fir; +    ad937x_fir(); +    ad937x_fir(int8_t gain, const std::vector<int16_t>& coefficients); + +    void set_fir(int8_t gain, const std::vector<int16_t>& coefficients); +    std::vector<int16_t> get_fir(int8_t &gain); +}; diff --git a/mpm/lib/mykonos/config/mykonos_default_config.h b/mpm/lib/mykonos/config/mykonos_default_config.h deleted file mode 100644 index a5ed4fe6c..000000000 --- a/mpm/lib/mykonos/config/mykonos_default_config.h +++ /dev/null @@ -1,359 +0,0 @@ -#include "../adi/t_mykonos.h" - -// This file is more or less the static config provided by a run of the eval software -// except all pointers have been changed to NULL -// Hopefully this helps the compiler use these as purely constants -// The pointers should be filled in if these data structures are to be actually used with the API - -static const mykonosRxSettings_t DEFAULT_RX_SETTINGS = -{ -    NULL,           /* Rx datapath profile, 3dB corner frequencies, and digital filter enables*/ -    NULL,           /* Rx JESD204b framer configuration structure*/ -    NULL,           /* Rx Gain control settings structure*/ -    NULL,           /* Rx AGC control settings structure*/ -    RX1_RX2,        /* The desired Rx Channels to enable during initialization*/ -    0,              /* Internal LO = 0, external LO*2 = 1*/ -    3500000000U, /* Rx PLL LO Frequency (internal or external LO)*/ -    0               /* Flag to choose if complex baseband or real IF data are selected for Rx and ObsRx paths. Where, if > 0 = real IF data, '0' = zero IF (IQ) data*/ -}; - -static const mykonosRxProfile_t DEFAULT_RX_PROFILE = -{/* Rx 100MHz, IQrate 122.88MHz, Dec5 */ -    1,              /* The divider used to generate the ADC clock*/ -    NULL,           /* Pointer to Rx FIR filter structure*/ -    2,              /* Rx FIR decimation (1,2,4)*/ -    5,              /* Decimation of Dec5 or Dec4 filter (5,4)*/ -    1,              /* If set, and DEC5 filter used, will use a higher rejection DEC5 FIR filter (1=Enabled, 0=Disabled)*/ -    1,              /* RX Half band 1 decimation (1 or 2)*/ -    122880,         /* Rx IQ data rate in kHz*/ -    100000000,    /* The Rx RF passband bandwidth for the profile*/ -    100000,         /* Rx BBF 3dB corner in kHz*/ -    NULL            /* pointer to custom ADC profile*/ -}; - -static const mykonosJesd204bFramerConfig_t DEFAULT_FRAMER = -{ -    0,              /* JESD204B Configuration Bank ID -extension to Device ID (Valid 0..15)*/ -    0,              /* JESD204B Configuration Device ID - link identification number. (Valid 0..255)*/ -    0,              /* JESD204B Configuration starting Lane ID.  If more than one lane used, each lane will increment from the Lane0 ID. (Valid 0..31)*/ -    4,              /* number of ADCs (0, 2, or 4) - 2 ADCs per receive chain*/ -    32,             /* number of frames in a multiframe (default=32), F*K must be a multiple of 4. (F=2*M/numberOfLanes)*/ -    1,              /* scrambling off if framerScramble= 0, if framerScramble>0 scramble is enabled.*/ -    1,              /* 0=use internal SYSREF, 1= use external SYSREF*/ -    0x0F,           /* serializerLanesEnabled - bit per lane, [0] = Lane0 enabled, [1] = Lane1 enabled*/ -    0xE4,           /* serializerLaneCrossbar*/ -    26,             /* serializerAmplitude - default 22 (valid (0-31)*/ -    0,              /* preEmphasis - < default 4 (valid 0 - 7)*/ -    0,              /* invertLanePolarity - default 0 ([0] will invert lane [0], bit1 will invert lane1)*/ -    0,              /* lmfcOffset - LMFC offset value for deterministic latency setting*/ -    0,              /* Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, 0 = not set*/ -    0,              /* Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set*/ -    0,              /* Selects SYNCb input source. Where, 0 = use RXSYNCB for this framer, 1 = use OBSRX_SYNCB for this framer*/ -    0,              /* Flag for determining if CMOS mode for RX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS*/ -    0               /* Selects framer bit repeat or oversampling mode for lane rate matching. Where, 0 = bitRepeat mode (changes effective lanerate), 1 = overSample (maintains same lane rate between ObsRx framer and Rx framer and oversamples the ADC samples)*/ -}; - -static const mykonosRxGainControl_t DEFAULT_RX_GAIN = -{ -    MGC,            /* Current Rx gain control mode setting*/ -    255,            /* Rx1 Gain Index, can be used in different ways for manual and AGC gain control*/ -    255,            /* Rx2 Gain Index, can be used in different ways for manual and AGC gain control*/ -    255,            /* Max gain index for the currently loaded Rx1 Gain table*/ -    195,            /* Min gain index for the currently loaded Rx1 Gain table*/ -    255,            /* Max gain index for the currently loaded Rx2 Gain table*/ -    195,            /* Min gain index for the currently loaded Rx2 Gain table*/ -    0,              /* Stores Rx1 RSSI value read back from the Mykonos*/ -    0               /* Stores Rx2 RSSI value read back from the Mykonos*/ -}; - -static const mykonosPeakDetAgcCfg_t DEFAULT_RX_PEAK_AGC = -{ -    0x1F,	/* apdHighThresh: */ -    0x16,	/* apdLowThresh */ -    0xB5,	/* hb2HighThresh */ -    0x80,	/* hb2LowThresh */ -    0x40,	/* hb2VeryLowThresh */ -    0x06,	/* apdHighThreshExceededCnt */ -    0x04,	/* apdLowThreshExceededCnt */ -    0x06,	/* hb2HighThreshExceededCnt */ -    0x04,	/* hb2LowThreshExceededCnt */ -    0x04,	/* hb2VeryLowThreshExceededCnt */ -    0x4,	/* apdHighGainStepAttack */ -    0x2,	/* apdLowGainStepRecovery */ -    0x4,	/* hb2HighGainStepAttack */ -    0x2,	/* hb2LowGainStepRecovery */ -    0x4,	/* hb2VeryLowGainStepRecovery */ -    0x1,	/* apdFastAttack */ -    0x1,	/* hb2FastAttack */ -    0x1,	/* hb2OverloadDetectEnable */ -    0x1,	/* hb2OverloadDurationCnt */ -    0x1	    /* hb2OverloadThreshCnt */ -}; - -static const mykonosPowerMeasAgcCfg_t DEFAULT_RX_POWER_AGC = -{ -    0x01,	/* pmdUpperHighThresh */ -    0x03,	/* pmdUpperLowThresh */ -    0x0C,	/* pmdLowerHighThresh */ -    0x04,	/* pmdLowerLowThresh */ -    0x4,	/* pmdUpperHighGainStepAttack */ -    0x2,	/* pmdUpperLowGainStepAttack */ -    0x2,	/* pmdLowerHighGainStepRecovery */ -    0x4,	/* pmdLowerLowGainStepRecovery */ -    0x08,	/* pmdMeasDuration */ -    0x02	/* pmdMeasConfig */ -}; - -static const mykonosAgcCfg_t DEFAULT_RX_AGC_CTRL = -{ -    255,	/* AGC peak wait time */ -    195,	/* agcRx1MinGainIndex */ -    255,	/* agcRx2MaxGainIndex */ -    195,	/* agcRx2MinGainIndex: */ -    255,	/* agcObsRxMaxGainIndex */ -    203,	/* agcObsRxMinGainIndex */ -    1,		/* agcObsRxSelect */ -    1,		/* agcPeakThresholdMode */ -    1,		/* agcLowThsPreventGainIncrease */ -    30720,	/* agcGainUpdateCounter */ -    3,	    /* agcSlowLoopSettlingDelay */ -    2,	    /* agcPeakWaitTime */ -    0,	    /* agcResetOnRxEnable */ -    0,	    /* agcEnableSyncPulseForGainCounter */ -    NULL, -    NULL -}; - -static const mykonosTxSettings_t DEFAULT_TX_SETTINGS = -{ -    NULL,           /* Tx datapath profile, 3dB corner frequencies, and digital filter enables*/ -    NULL,           /* Mykonos JESD204b deframer config for the Tx data path*/ -    TX1_TX2,        /* The desired Tx channels to enable during initialization*/ -    0,              /* Internal LO=0, external LO*2 if =1*/ -    3500000000U, /* Tx PLL LO frequency (internal or external LO)*/ -    TXATTEN_0P05_DB,/* Initial and current Tx1 Attenuation*/ -    10000,          /* Initial and current Tx1 Attenuation mdB*/ -    10000,          /* Initial and current Tx2 Attenuation mdB*/ -    NULL,           /* DPD,CLGC,VSWR settings. Only valid for AD9373 device, set pointer to NULL otherwise*/ -    NULL,           /* CLGC Config Structure. Only valid for AD9373 device, set pointer to NULL otherwise*/ -    NULL            /* VSWR Config Structure. Only valid for AD9373 device, set pointer to NULL otherwise*/ -}; - -static const mykonosTxProfile_t DEFAULT_TX_PROFILE = -{ /* Tx 20/100MHz, IQrate 122.88MHz, Dec5 */ -    DACDIV_2p5,     /* The divider used to generate the DAC clock*/ -    NULL,           /* Pointer to Tx FIR filter structure*/ -    2,              /* The Tx digital FIR filter interpolation (1,2,4)*/ -    2,              /* Tx Halfband1 filter interpolation (1,2)*/ -    1,              /* Tx Halfband2 filter interpolation (1,2)*/ -    1,              /* TxInputHbInterpolation (1,2)*/ -    122880,         /* Tx IQ data rate in kHz*/ -    20000000,       /* Primary Signal BW*/ -    100000000,    /* The Tx RF passband bandwidth for the profile*/ -    710539,         /* The DAC filter 3dB corner in kHz*/ -    50000,          /* Tx BBF 3dB corner in kHz*/ -    0               /* Enable DPD, only valid for AD9373*/ -}; - -static const mykonosJesd204bDeframerConfig_t DEFAULT_DEFRAMER = -{ -    0,              /* bankId extension to Device ID (Valid 0..15)*/ -    0,              /* deviceId  link identification number. (Valid 0..255)*/ -    0,              /* lane0Id Lane0 ID. (Valid 0..31)*/ -    4,              /* M  number of DACss (0, 2, or 4) - 2 DACs per transmit chain */ -    32,             /* K  #frames in a multiframe (default=32), F*K=multiple of 4. (F=2*M/numberOfLanes)*/ -    0,              /* Scrambling off if scramble = 0, if framerScramble > 0 scrambling is enabled*/ -    1,              /* External SYSREF select. 0 = use internal SYSREF, 1 = external SYSREF*/ -    0x0F,           /* Deserializer lane select bit field. Where, [0] = Lane0 enabled, [1] = Lane1 enabled, etc */ -    0xE4,           /* Lane crossbar to map physical lanes to deframer lane inputs [1:0] = Deframer Input 0 Lane section, [3:2] = Deframer Input 1 lane select, etc */ -    1,              /* Equalizer setting. Applied to all deserializer lanes. Range is 0..4*/ -    0,              /* PN inversion per each lane.  bit[0] = 1 Invert PN of Lane 0, bit[1] = Invert PN of Lane 1, etc).*/ -    0,              /* LMFC offset value to adjust deterministic latency. Range is 0..31*/ -    0,              /* Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, '0' = not set*/ -    0,              /* Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set*/ -    0               /* Flag for determining if CMOS mode for TX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS*/ -}; - -static const mykonosObsRxSettings_t DEFAULT_ORX_SETTINGS = -{ -    NULL,           /* ORx datapath profile, 3dB corner frequencies, and digital filter enables*/ -    NULL,           /* ObsRx gain control settings structure*/ -    NULL,           /* ORx AGC control settings structure*/ -    NULL,           /* Sniffer datapath profile, 3dB corner frequencies, and digital filter enables*/ -    NULL,           /* SnRx gain control settings structure*/ -    NULL,           /* ObsRx JESD204b framer configuration structure */ -    MYK_OBS_RXOFF,  /* obsRxChannel */ -    OBSLO_TX_PLL,   /* (obsRxLoSource) The Obs Rx mixer can use the Tx Synth(TX_PLL) or Sniffer Synth (SNIFFER_PLL) */ -    2600000000U, /* SnRx PLL LO frequency in Hz */ -    0,              /* Flag to choose if complex baseband or real IF data are selected for Rx and ObsRx paths. Where if > 0 = real IF data, '0' = complex data*/ -    NULL,           /* Custom Loopback ADC profile to set the bandwidth of the ADC response */ -    OBS_RXOFF       /* Default ObsRx channel to enter when radioOn called */ -}; - -static const mykonosJesd204bFramerConfig_t DEFAULT_ORX_FRAMER = -{ -    0,              /* JESD204B Configuration Bank ID -extension to Device ID (Valid 0..15)*/ -    0,              /* JESD204B Configuration Device ID - link identification number. (Valid 0..255)*/ -    0,              /* JESD204B Configuration starting Lane ID.  If more than one lane used, each lane will increment from the Lane0 ID. (Valid 0..31)*/ -    2,              /* number of ADCs (0, 2, or 4) - 2 ADCs per receive chain*/ -    32,             /* number of frames in a multiframe (default=32), F*K must be a multiple of 4. (F=2*M/numberOfLanes)*/ -    1,              /* scrambling off if framerScramble= 0, if framerScramble>0 scramble is enabled.*/ -    1,              /* 0=use internal SYSREF, 1= use external SYSREF*/ -    0x00,           /* serializerLanesEnabled - bit per lane, [0] = Lane0 enabled, [1] = Lane1 enabled*/ -    0xE4,           /* Lane crossbar to map framer lane outputs to physical lanes*/ -    22,             /* serializerAmplitude - default 22 (valid (0-31)*/ -    4,              /* preEmphasis - < default 4 (valid 0 - 7)*/ -    0,              /* invertLanePolarity - default 0 ([0] will invert lane [0], bit1 will invert lane1)*/ -    0,              /* lmfcOffset - LMFC_Offset offset value for deterministic latency setting*/ -    0,              /* Flag for determining if SYSREF on relink should be set. Where, if > 0 = set, 0 = not set*/ -    0,              /* Flag for determining if auto channel select for the xbar should be set. Where, if > 0 = set, '0' = not set*/ -    1,              /* Selects SYNCb input source. Where, 0 = use RXSYNCB for this framer, 1 = use OBSRX_SYNCB for this framer*/ -    0,              /* Flag for determining if CMOS mode for RX Sync signal is used. Where, if > 0 = CMOS, '0' = LVDS*/ -    1               /* Selects framer bit repeat or oversampling mode for lane rate matching. Where, 0 = bitRepeat mode (changes effective lanerate), 1 = overSample (maintains same lane rate between ObsRx framer and Rx framer and oversamples the ADC samples)*/ -}; - -static const mykonosORxGainControl_t DEFAULT_ORX_GAIN = -{ -    MGC,            /* Current ORx gain control mode setting*/ -    255,            /* ORx1 Gain Index, can be used in different ways for manual and AGC gain control*/ -    255,            /* ORx2 Gain Index, can be used in different ways for manual and AGC gain control*/ -    255,            /* Max gain index for the currently loaded ORx Gain table*/ -    237             /* Min gain index for the currently loaded ORx Gain table*/ -}; - -static const mykonosAgcCfg_t DEFAULT_ORX_AGC_CTRL = -{ -    0,	/* agcRx1MaxGainIndex */ -    0,	/* agcRx1MinGainIndex */ -    0,	/* agcRx2MaxGainIndex */ -    0,	/* agcRx2MinGainIndex: */ -    0,	/* agcObsRxMaxGainIndex */ -    0,	/* agcObsRxMinGainIndex */ -    0,		/* agcObsRxSelect */ -    0,		/* agcPeakThresholdMode */ -    0,		/* agcLowThsPreventGainIncrease */ -    0,	/* agcGainUpdateCounter */ -    0,	/* agcSlowLoopSettlingDelay */ -    0,	/* agcPeakWaitTime */ -    0,	/* agcResetOnRxEnable */ -    0,	/* agcEnableSyncPulseForGainCounter */ -    NULL, -    NULL -}; - -static const mykonosPeakDetAgcCfg_t DEFAULT_ORX_PEAK_AGC = -{ -    0x00,	/* apdHighThresh: */ -    0x00,	/* apdLowThresh */ -    0x00,	/* hb2HighThresh */ -    0x00,	/* hb2LowThresh */ -    0x00,	/* hb2VeryLowThresh */ -    0x00,	/* apdHighThreshExceededCnt */ -    0x00,	/* apdLowThreshExceededCnt */ -    0x00,	/* hb2HighThreshExceededCnt */ -    0x00,	/* hb2LowThreshExceededCnt */ -    0x00,	/* hb2VeryLowThreshExceededCnt */ -    0x0,	/* apdHighGainStepAttack */ -    0x0,	/* apdLowGainStepRecovery */ -    0x0,	/* hb2HighGainStepAttack */ -    0x0,	/* hb2LowGainStepRecovery */ -    0x0,	/* hb2VeryLowGainStepRecovery */ -    0x0,	/* apdFastAttack */ -    0x0,	/* hb2FastAttack */ -    0x0,	/* hb2OverloadDetectEnable */ -    0x0,	/* hb2OverloadDurationCnt */ -    0x0		/* hb2OverloadThreshCnt */ -}; - -static const mykonosPowerMeasAgcCfg_t DEFAULT_ORX_POWER_AGC = -{ -    0x00,	/* pmdUpperHighThresh */ -    0x00,	/* pmdUpperLowThresh */ -    0x00,	/* pmdLowerHighThresh */ -    0x00,	/* pmdLowerLowThresh */ -    0x0,	/* pmdUpperHighGainStepAttack */ -    0x0,	/* pmdUpperLowGainStepAttack */ -    0x0,	/* pmdLowerHighGainStepRecovery */ -    0x0,	/* pmdLowerLowGainStepRecovery */ -    0x00,	/* pmdMeasDuration */ -    0x00	/* pmdMeasConfig */ -}; - -static const mykonosRxProfile_t DEFAULT_ORX_PROFILE = -{/* ORX 100MHz, IQrate 125MSPS, Dec5 */ -    1,              /* The divider used to generate the ADC clock*/ -    NULL,           /* Pointer to Rx FIR filter structure or NULL*/ -    2,              /* Rx FIR decimation (1,2,4)*/ -    5,              /* Decimation of Dec5 or Dec4 filter (5,4)*/ -    0,              /* If set, and DEC5 filter used, will use a higher rejection DEC5 FIR filter (1=Enabled, 0=Disabled)*/ -    1,              /* RX Half band 1 decimation (1 or 2)*/ -    125000,        /* Rx IQ data rate in kHz*/ -    100000000,    /* The Rx RF passband bandwidth for the profile*/ -    102000,        /* Rx BBF 3dB corner in kHz*/ -    NULL            /* pointer to custom ADC profile*/ -}; - -static const mykonosArmGpioConfig_t DEFAULT_ARM_GPIO = -{ -    0,	// useRx2EnablePin; /*!< 0= RX1_ENABLE controls RX1 and RX2, 1 = separate RX1_ENABLE/RX2_ENABLE pins */ -    0,	// useTx2EnablePin; /*!< 0= TX1_ENABLE controls TX1 and TX2, 1 = separate TX1_ENABLE/TX2_ENABLE pins */ -    0,	// txRxPinMode;     /*!< 0= ARM command mode, 1 = Pin mode to power up Tx/Rx chains */ -    0,	// orxPinMode;      /*!< 0= ARM command mode, 1 = Pin mode to power up ObsRx receiver*/ - -    /*Mykonos ARM input GPIO pins -- Only valid if orxPinMode = 1 */ -    0,	// orxTriggerPin; /*!< Select desired GPIO pin (valid 4-15) */ -    0,	// orxMode2Pin;   /*!< Select desired GPIO pin (valid 0-18) */ -    0,	// orxMode1Pin;   /*!< Select desired GPIO pin (valid 0-18) */ -    0,	// orxMode0Pin;   /*!< Select desired GPIO pin (valid 0-18) */ - -    /* Mykonos ARM output GPIO pins  --  always available, even when pin mode not enabled*/ -    0,	// rx1EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ -    0,	// rx2EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ -    0,	// tx1EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ -    0,	// tx2EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ -    0,	// orx1EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ -    0,	// orx2EnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ -    0,	// srxEnableAck;  /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ -    0 	// txObsSelect;   /*!< Select desired GPIO pin (0-15), [4] = Output Enable */ -        /* When 2Tx are used with only 1 ORx input, this GPIO tells the BBIC which Tx channel is   */ -        /* active for calibrations, so BBIC can route correct RF Tx path into the single ORx input*/ -}; - -static const mykonosGpio3v3_t DEFAULT_GPIO_3V3 = -{ -    0,				/*!< Oe per pin, 1=output, 0 = input */ -    GPIO3V3_BITBANG_MODE,	/*!< Mode for GPIO3V3[3:0] */ -    GPIO3V3_BITBANG_MODE,	/*!< Mode for GPIO3V3[7:4] */ -    GPIO3V3_BITBANG_MODE,	/*!< Mode for GPIO3V3[11:8] */ -}; - -static const mykonosGpioLowVoltage_t DEFAULT_GPIO = -{ -    0,/* Oe per pin, 1=output, 0 = input */ -    GPIO_MONITOR_MODE,/* Mode for GPIO[3:0] */ -    GPIO_MONITOR_MODE,/* Mode for GPIO[7:4] */ -    GPIO_MONITOR_MODE,/* Mode for GPIO[11:8] */ -    GPIO_MONITOR_MODE,/* Mode for GPIO[15:12] */ -    GPIO_MONITOR_MODE,/* Mode for GPIO[18:16] */ -}; - -static const mykonosAuxIo_t DEFAULT_AUX_IO = -{ -    0,	//auxDacEnableMask uint16_t -    { 0,0,0,0,0,0,0,0,0,0 },	 //AuxDacValue uint16[10] -    { 0,0,0,0,0,0,0,0,0,0 },	 //AuxDacSlope uint8[10] -    { 0,0,0,0,0,0,0,0,0,0 },	 //AuxDacVref uint8[10] -    NULL,	//pointer to gpio3v3 struct -    NULL,	//pointer to gpio1v8 struct -    NULL -}; - -static const mykonosDigClocks_t DEFAULT_CLOCKS = -{ -    122880,         /* CLKPLL and device reference clock frequency in kHz*/ -    9830400,        /* CLKPLL VCO frequency in kHz*/ -    VCODIV_2,       /* CLKPLL VCO divider*/ -    4               /* CLKPLL high speed clock divider*/ -}; - - | 
