aboutsummaryrefslogtreecommitdiffstats
path: root/mpm/lib/mykonos/ad937x_device.cpp
diff options
context:
space:
mode:
authormattprost <matt.prost@ni.com>2021-12-16 13:48:26 -0600
committerAaron Rossetto <aaron.rossetto@ni.com>2022-04-07 13:28:02 -0700
commitb8acf58798018f5fb4d84d470badadce5dd3a08d (patch)
tree137db7eeff0d3bbc202b228fd4bee4f143b1b467 /mpm/lib/mykonos/ad937x_device.cpp
parenta8ad4917d331258e163e1786c0325a4b7e7d2e3e (diff)
downloaduhd-b8acf58798018f5fb4d84d470badadce5dd3a08d.tar.gz
uhd-b8acf58798018f5fb4d84d470badadce5dd3a08d.tar.bz2
uhd-b8acf58798018f5fb4d84d470badadce5dd3a08d.zip
n310: Add Filter API to n310
Add the Filter API to n3xx specifically for the AD937x device. The TX filter is limited to 32 taps, and the RX filter is limited to 48 taps. This feature requires MPM version 4.2 or later on the device. Co-authored-by: bpadalino <bpadalino@gmail.com> Signed-off-by: mattprost <matt.prost@ni.com>
Diffstat (limited to 'mpm/lib/mykonos/ad937x_device.cpp')
-rw-r--r--mpm/lib/mykonos/ad937x_device.cpp71
1 files changed, 61 insertions, 10 deletions
diff --git a/mpm/lib/mykonos/ad937x_device.cpp b/mpm/lib/mykonos/ad937x_device.cpp
index fba065983..1a1905004 100644
--- a/mpm/lib/mykonos/ad937x_device.cpp
+++ b/mpm/lib/mykonos/ad937x_device.cpp
@@ -10,6 +10,7 @@
#include "adi/mykonos_gpio.h"
#include "config/ad937x_config_t.hpp"
#include "config/ad937x_default_config.hpp"
+#include "mpm/ad937x/ad937x_ctrl.hpp"
#include <uhd/utils/algorithm.hpp>
#include <boost/format.hpp>
#include <cmath>
@@ -20,6 +21,7 @@
using namespace mpm::ad937x::device;
using namespace mpm::ad937x::gpio;
+using namespace mpm::chips;
using namespace uhd;
const double ad937x_device::MIN_FREQ = 300e6;
@@ -59,6 +61,20 @@ static constexpr double AD9371_TX_DAC_FILT_MAX_CORNER = 187.0e6; // Hz
static const uint32_t PLL_LOCK_TIMEOUT_MS = 200;
+const std::map<std::string, mykonosfirName_t> ad937x_device::_tx_filter_map{
+ {"TX1_FIR", TX1_FIR},
+ {"TX2_FIR", TX2_FIR},
+ {"TX1TX2_FIR", TX1TX2_FIR},
+};
+
+const std::map<std::string, mykonosfirName_t> ad937x_device::_rx_filter_map{
+ {"RX1_FIR", RX1_FIR},
+ {"RX2_FIR", RX2_FIR},
+ {"RX1RX2_FIR", RX1RX2_FIR},
+ {"OBSRX_A_FIR", OBSRX_A_FIR},
+ {"OBSRX_B_FIR", OBSRX_B_FIR},
+};
+
// Amount of time to average samples for RX DC offset
// A larger averaging window will result in:
// Longer latency to correct DC offset changes
@@ -667,6 +683,28 @@ void ad937x_device::set_agc_mode(const direction_t direction, const gain_mode_t
}
void ad937x_device::set_fir(
+ const std::string& name, int8_t gain, const std::vector<int16_t>& fir)
+{
+ mykonosfirName_t filter_name;
+ if (_rx_filter_map.count(name) == 1) {
+ filter_name = _rx_filter_map.at(name);
+ mykonos_config.rx_fir_config.set_fir(gain, fir);
+ } else if (_tx_filter_map.count(name) == 1) {
+ filter_name = _tx_filter_map.at(name);
+ mykonos_config.tx_fir_config.set_fir(gain, fir);
+ } else {
+ throw mpm::runtime_error("set_fir invalid name: " + name);
+ }
+ mykonosFir_t filter{.gain_dB = gain,
+ .numFirCoefs = static_cast<uint8_t>(fir.size()),
+ .coefs = const_cast<int16_t*>(fir.data())};
+ const auto state = _move_to_config_state();
+ CALL_API(MYKONOS_programFir(mykonos_config.device, filter_name, &filter));
+ _restore_from_config_state(state);
+}
+
+
+void ad937x_device::set_fir(
const direction_t direction, int8_t gain, const std::vector<int16_t>& fir)
{
switch (direction) {
@@ -679,8 +717,13 @@ void ad937x_device::set_fir(
default:
MPM_THROW_INVALID_CODE_PATH();
}
-
- // TODO: reload this on device
+ mykonosfirName_t filter_name = (direction == TX_DIRECTION) ? TX1TX2_FIR : RX1RX2_FIR;
+ mykonosFir_t filter{.gain_dB = gain,
+ .numFirCoefs = static_cast<uint8_t>(fir.size()),
+ .coefs = const_cast<int16_t*>(fir.data())};
+ const auto state = _move_to_config_state();
+ CALL_API(MYKONOS_programFir(mykonos_config.device, filter_name, &filter));
+ _restore_from_config_state(state);
}
void ad937x_device::set_gain_pin_step_sizes(const direction_t direction,
@@ -795,16 +838,24 @@ double ad937x_device::get_gain(const direction_t direction, const chain_t chain)
}
}
-std::vector<int16_t> ad937x_device::get_fir(const direction_t direction, int8_t& gain)
+std::pair<int8_t, std::vector<int16_t>> ad937x_device::get_fir(const std::string& name)
{
- switch (direction) {
- case TX_DIRECTION:
- return mykonos_config.tx_fir_config.get_fir(gain);
- case RX_DIRECTION:
- return mykonos_config.rx_fir_config.get_fir(gain);
- default:
- MPM_THROW_INVALID_CODE_PATH();
+ mykonosfirName_t filter_name;
+ if (_rx_filter_map.count(name) == 1) {
+ filter_name = _rx_filter_map.at(name);
+ } else if (_tx_filter_map.count(name) == 1) {
+ filter_name = _tx_filter_map.at(name);
+ } else {
+ throw mpm::runtime_error("get_fir invalid name: " + name);
}
+ mykonosFir_t fir;
+ std::vector<int16_t> rv(96, 0);
+ fir.coefs = rv.data();
+ const auto state = _move_to_config_state();
+ CALL_API(MYKONOS_readFir(mykonos_config.device, filter_name, &fir));
+ _restore_from_config_state(state);
+ rv.resize(fir.numFirCoefs);
+ return std::pair<int8_t, std::vector<int16_t>>(fir.gain_dB, rv);
}
int16_t ad937x_device::get_temperature()