mirror of
https://github.com/EttusResearch/uhd.git
synced 2026-10-25 17:36:10 +00:00
mpm: Rearchitecture of AD9371 code to use ctrl/device paradigm
This commit is contained in:
parent
1a4348038d
commit
bc4d1bf0ca
1
mpm/.gitignore
vendored
1
mpm/.gitignore
vendored
@ -1 +1,2 @@
|
||||
build
|
||||
msvcbuild
|
||||
@ -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;
|
||||
};
|
||||
|
||||
|
||||
@ -32,7 +32,6 @@ SET(mykonos_sources
|
||||
)
|
||||
|
||||
ADD_SUBDIRECTORY(adi)
|
||||
ADD_SUBDIRECTORY(adi_sample)
|
||||
ADD_SUBDIRECTORY(config)
|
||||
|
||||
USRP_PERIPHS_ADD_OBJECT(mykonos ${mykonos_sources})
|
||||
|
||||
@ -1,15 +1,31 @@
|
||||
//
|
||||
// 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 "ad937x_ctrl.hpp"
|
||||
#include "adi/mykonos.h"
|
||||
|
||||
#include "ad937x_ctrl.hpp"
|
||||
#include "ad937x_device.hpp"
|
||||
#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);
|
||||
|
||||
std::lock_guard<spi_lock> lock(*spi_l);
|
||||
device.set_fir(dir, chain, gain, fir);
|
||||
}
|
||||
virtual std::vector<int16_t> get_fir(const std::string &which) = 0;
|
||||
|
||||
virtual int16_t get_temperature() = 0;
|
||||
std::vector<int16_t> get_fir(const std::string &which, int8_t &gain)
|
||||
{
|
||||
auto dir = _get_direction_from_antenna(which);
|
||||
auto chain = _get_chain_from_antenna(which);
|
||||
|
||||
std::lock_guard<spi_lock> lock(*spi_l);
|
||||
return device.get_fir(dir, chain, gain);
|
||||
}
|
||||
|
||||
virtual int16_t get_temperature()
|
||||
{
|
||||
std::lock_guard<spi_lock> lock(*spi_l);
|
||||
return device.get_temperature();
|
||||
}
|
||||
|
||||
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)
|
||||
ad937x_ctrl::sptr ad937x_ctrl::make(spi_lock::sptr spi_l, uhd::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));
|
||||
}
|
||||
return static_cast<double>(coerced_pll);
|
||||
}
|
||||
|
||||
double ad937x_ctrl::get_freq(direction_t direction)
|
||||
{
|
||||
mykonosRfPllName_t pll;
|
||||
switch (direction)
|
||||
{
|
||||
case TX: pll = TX_PLL; break;
|
||||
case RX: pll = RX_PLL; break;
|
||||
default:
|
||||
// TODO: bad code path exception
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
// 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 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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
double ad937x_ctrl::set_agc_mode(direction_t direction, chain_t chain, gain_mode_t mode)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
@ -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);
|
||||
};
|
||||
@ -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);
|
||||
}
|
||||
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;
|
||||
|
||||
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();
|
||||
}
|
||||
// TODO: get the actual device ID
|
||||
static const uint32_t AD9371_PRODUCT_ID = 0x1F;
|
||||
|
||||
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: move this to whereever we declare the ARM binary
|
||||
static const size_t ARM_BINARY_SIZE = 98304;
|
||||
|
||||
//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;
|
||||
static const uint32_t INIT_CAL_TIMEOUT_MS = 10000;
|
||||
|
||||
initialize();
|
||||
}
|
||||
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)
|
||||
{
|
||||
auto error = func();
|
||||
if (error != MYKONOS_ERR_GPIO_OK)
|
||||
{
|
||||
std::cout << getGpioMykonosErrorMessage(error);
|
||||
// TODO: make UHD exception
|
||||
//throw std::exception(getMykonosErrorMessage(error));
|
||||
}
|
||||
}
|
||||
|
||||
void ad937x_device::_initialize()
|
||||
{
|
||||
_call_api_function(std::bind(MYKONOS_resetDevice, mykonos_config.device));
|
||||
|
||||
if (get_product_id() != AD9371_PRODUCT_ID)
|
||||
{
|
||||
throw uhd::runtime_error("AD9371 product ID does not match expected ID!");
|
||||
}
|
||||
|
||||
_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()");
|
||||
}
|
||||
|
||||
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()");
|
||||
}
|
||||
if (!get_pll_lock_status(pll_t::TX_SYNTH))
|
||||
{
|
||||
throw uhd::runtime_error("AD937x TX PLL failed to lock in initialize()");
|
||||
}
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
// TODO: review const-ness in this function with respect to ADI API
|
||||
void ad937x_device::_load_arm(std::vector<uint8_t> & binary)
|
||||
{
|
||||
_call_api_function(std::bind(MYKONOS_initArm, mykonos_config.device));
|
||||
|
||||
if (binary.size() == ARM_BINARY_SIZE)
|
||||
{
|
||||
throw uhd::runtime_error("ad937x_device ARM is not the correct size!");
|
||||
}
|
||||
|
||||
_call_api_function(std::bind(MYKONOS_loadArmFromBinary, mykonos_config.device, &binary[0], binary.size()));
|
||||
}
|
||||
|
||||
void ad937x_device::_run_initialization_calibrations()
|
||||
{
|
||||
_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))
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
std::lock_guard<spi_lock> lock(*spi_l);
|
||||
uint8_t id;
|
||||
call_api_function(std::bind(MYKONOS_getProductId, mykonos_config.device, &id));
|
||||
_call_api_function(std::bind(MYKONOS_getProductId, mykonos_config.device, &id));
|
||||
return id;
|
||||
}
|
||||
|
||||
double ad937x_ctrl::set_clock_rate(const double req_rate)
|
||||
uint8_t ad937x_device::get_device_rev()
|
||||
{
|
||||
auto rate = static_cast<decltype(mykonos_config.device->clocks->deviceClock_kHz)>(req_rate / 1000);
|
||||
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()
|
||||
{
|
||||
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;
|
||||
{
|
||||
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);
|
||||
_call_api_function(std::bind(MYKONOS_initDigitalClocks, mykonos_config.device));
|
||||
return static_cast<double>(rate);
|
||||
}
|
||||
|
||||
void ad937x_ctrl::_set_active_tx_chains(bool tx1, bool tx2)
|
||||
void ad937x_device::enable_channel(uhd::direction_t direction, chain_t chain, bool enable)
|
||||
{
|
||||
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;
|
||||
// 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.
|
||||
}
|
||||
|
||||
void ad937x_ctrl::_set_active_rx_chains(bool rx1, bool rx2)
|
||||
double ad937x_device::tune(uhd::direction_t direction, double value)
|
||||
{
|
||||
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
|
||||
// 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;
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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_SLOW_AGC:
|
||||
case GAIN_MODE_FAST_AGC:
|
||||
// TODO: differentiate these
|
||||
call_api_function(std::bind(MYKONOS_setupRxAgc, mykonos_config.device));
|
||||
case gain_mode_t::AUTOMATIC:
|
||||
_call_api_function(std::bind(MYKONOS_setRxGainControlMode, mykonos_config.device, AGC));
|
||||
break;
|
||||
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();
|
||||
}
|
||||
return double();
|
||||
}
|
||||
|
||||
ad937x_ctrl::sptr ad937x_ctrl::make(spi_lock::sptr spi_l, mpm::spi_iface::sptr iface)
|
||||
void ad937x_device::set_fir(
|
||||
const uhd::direction_t direction,
|
||||
const chain_t chain,
|
||||
int8_t gain,
|
||||
const std::vector<int16_t> & fir)
|
||||
{
|
||||
return std::make_shared<ad937x_ctrl>(spi_l, iface);
|
||||
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();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
std::vector<int16_t> ad937x_device::get_fir(
|
||||
const uhd::direction_t direction,
|
||||
const chain_t chain,
|
||||
int8_t &gain)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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);
|
||||
void _call_api_function(std::function<mykonosErr_t()> func);
|
||||
void _call_gpio_api_function(std::function<mykonosGpioErr_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;
|
||||
};
|
||||
|
||||
const double ad937x_ctrl::MIN_FREQ = 300e6;
|
||||
const double ad937x_ctrl::MAX_FREQ = 6e9;
|
||||
static uint8_t _convert_rx_gain(double gain);
|
||||
static uint16_t _convert_tx_gain(double gain);
|
||||
};
|
||||
@ -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
|
||||
)
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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 */
|
||||
@ -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)
|
||||
{
|
||||
CMB_TRACE_FUNCTION;
|
||||
return COMMONERR_OK;
|
||||
}
|
||||
commonErr_t CMB_setTimeout_us(uint32_t timeOut_us)
|
||||
{
|
||||
CMB_TRACE_FUNCTION;
|
||||
return COMMONERR_OK;
|
||||
}
|
||||
commonErr_t CMB_hasTimeoutExpired()
|
||||
{
|
||||
CMB_TRACE_FUNCTION;
|
||||
return COMMONERR_FAILED;
|
||||
}
|
||||
|
||||
/* platform logging functions */
|
||||
commonErr_t CMB_setTimeout_ms(spiSettings_t *spiSettings, uint32_t timeOut_ms)
|
||||
{
|
||||
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(spiSettings_t *spiSettings, uint32_t timeOut_us)
|
||||
{
|
||||
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(spiSettings_t *spiSettings)
|
||||
{
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
MYKONOS_APPEND_SOURCES(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/headless.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/mykonos_static_config.c
|
||||
)
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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);
|
||||
@ -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 */
|
||||
};
|
||||
@ -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
|
||||
@ -1,8 +1,27 @@
|
||||
#include "ad937x_config_t.h"
|
||||
#include "mykonos_default_config.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/>.
|
||||
//
|
||||
|
||||
ad937x_config_t::ad937x_config_t()
|
||||
#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 });
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
376
mpm/lib/mykonos/config/ad937x_default_config.hpp
Normal file
376
mpm/lib/mykonos/config/ad937x_default_config.hpp
Normal file
@ -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
|
||||
};
|
||||
|
||||
|
||||
@ -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)
|
||||
#include "ad937x_fir.hpp"
|
||||
|
||||
ad937x_fir::ad937x_fir() :
|
||||
ad937x_fir(0, { 1, 0 })
|
||||
{
|
||||
|
||||
_set_gain(gain);
|
||||
|
||||
}
|
||||
|
||||
ad937x_fir::ad937x_fir(int8_t gain, 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()})
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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();
|
||||
};
|
||||
|
||||
|
||||
35
mpm/lib/mykonos/config/ad937x_fir.hpp
Normal file
35
mpm/lib/mykonos/config/ad937x_fir.hpp
Normal file
@ -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);
|
||||
};
|
||||
@ -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*/
|
||||
};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user