aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mpm/include/mpm/ad937x/ad937x_ctrl.hpp91
-rw-r--r--mpm/lib/mykonos/ad937x_ctrl.cpp64
-rw-r--r--mpm/lib/mykonos/ad937x_device.cpp65
-rw-r--r--mpm/lib/mykonos/ad937x_device.hpp4
-rw-r--r--mpm/python/usrp_mpm/dboard_manager/magnesium.py23
5 files changed, 185 insertions, 62 deletions
diff --git a/mpm/include/mpm/ad937x/ad937x_ctrl.hpp b/mpm/include/mpm/ad937x/ad937x_ctrl.hpp
index 82e3d0ea2..22029a135 100644
--- a/mpm/include/mpm/ad937x/ad937x_ctrl.hpp
+++ b/mpm/include/mpm/ad937x/ad937x_ctrl.hpp
@@ -55,6 +55,46 @@ class ad937x_ctrl : public boost::noncopyable
{
public:
typedef std::shared_ptr<ad937x_ctrl> sptr;
+
+ static const uint32_t TX_BB_FILTER;
+ static const uint32_t ADC_TUNER;
+ static const uint32_t TIA_3DB_CORNER;
+ static const uint32_t DC_OFFSET;
+ static const uint32_t TX_ATTENUATION_DELAY;
+ static const uint32_t RX_GAIN_DELAY;
+ static const uint32_t FLASH_CAL;
+ static const uint32_t PATH_DELAY;
+ static const uint32_t TX_LO_LEAKAGE_INTERNAL;
+ static const uint32_t TX_LO_LEAKAGE_EXTERNAL ;
+ static const uint32_t TX_QEC_INIT;
+ static const uint32_t LOOPBACK_RX_LO_DELAY;
+ static const uint32_t LOOPBACK_RX_RX_QEC_INIT;
+ static const uint32_t RX_LO_DELAY;
+ static const uint32_t RX_QEC_INIT;
+ static const uint32_t DPD_INIT;
+ static const uint32_t CLGC_INIT;
+ static const uint32_t VSWR_INIT;
+ static const uint32_t TRACK_RX1_QEC;
+ static const uint32_t TRACK_RX2_QEC;
+ static const uint32_t TRACK_ORX1_QEC;
+ static const uint32_t TRACK_ORX2_QEC;
+ static const uint32_t TRACK_TX1_LOL;
+ static const uint32_t TRACK_TX2_LOL;
+ static const uint32_t TRACK_TX1_QEC;
+ static const uint32_t TRACK_TX2_QEC;
+ static const uint32_t TRACK_TX1_DPD;
+ static const uint32_t TRACK_TX2_DPD;
+ static const uint32_t TRACK_TX1_CLGC;
+ static const uint32_t TRACK_TX2_CLGC;
+ static const uint32_t TRACK_TX1_VSWR;
+ static const uint32_t TRACK_TX2_VSWR;
+ static const uint32_t TRACK_ORX1_QEC_SNLO;
+ static const uint32_t TRACK_ORX2_QEC_SNLO;
+ static const uint32_t TRACK_SRX_QEC;
+ static const uint32_t DEFAULT_INIT_CALS_MASKS;
+ static const uint32_t DEFAULT_TRACKING_CALS_MASKS;
+ static const uint32_t DEFAULT_INIT_CALS_TIMEOUT;
+
/*! \brief make a new AD9371 ctrl object using the specified SPI iface
*
* \param spi_mutex a mutex that will be locked whenever the SPI iface is to be used
@@ -72,7 +112,15 @@ public:
//! finishes initialization of the AD9371 by loading the ARM binary and setting a default RF configuration
virtual void finish_initialization() = 0;
-
+
+ /*! \setup initialization and tracking calibration
+ *
+ *\param init_cals_mask bit masking field for init calibration default to 0x4DFF
+ * NOTE: this init cals mask need to be at least 0x4F.
+ *\param tracking_cals_mask bit masking field for tracking calibration default to 0xC3
+ *\param timeout init calibration timeout. default to 10s
+ */
+ virtual void setup_cal(uint32_t init_cals_mask, uint32_t tracking_cals_mask, uint32_t timeout) = 0;
//! resets and start the JESD deframer (JESD Rx, for RF Tx)
virtual void start_jesd_rx() = 0;
@@ -211,9 +259,10 @@ public:
void export_mykonos(){
LIBMPM_BOOST_PREAMBLE("ad937x")
using namespace mpm::chips;
- bp::class_<ad937x_ctrl, boost::noncopyable, std::shared_ptr<ad937x_ctrl> >("ad937x_ctrl", bp::no_init)
+ bp::class_<ad937x_ctrl, boost::noncopyable, std::shared_ptr<ad937x_ctrl>>("ad937x_ctrl", bp::no_init)
.def("begin_initialization", &ad937x_ctrl::begin_initialization)
.def("finish_initialization", &ad937x_ctrl::finish_initialization)
+ .def("setup_cal", &ad937x_ctrl::setup_cal)
.def("start_jesd_rx", &ad937x_ctrl::start_jesd_rx)
.def("start_jesd_tx", &ad937x_ctrl::start_jesd_tx)
.def("start_radio", &ad937x_ctrl::start_radio)
@@ -242,6 +291,44 @@ void export_mykonos(){
.def("set_fir", &ad937x_ctrl::set_fir)
.def("get_fir", &ad937x_ctrl::get_fir)
.def("get_temperature", &ad937x_ctrl::get_temperature)
+ .def_readonly("TX_BB_FILTER", &ad937x_ctrl::TX_BB_FILTER)
+ .def_readonly("ADC_TUNER", &ad937x_ctrl::ADC_TUNER)
+ .def_readonly("TIA_3DB_CORNER", &ad937x_ctrl::TIA_3DB_CORNER)
+ .def_readonly("DC_OFFSET", &ad937x_ctrl::DC_OFFSET)
+ .def_readonly("TX_ATTENUATION_DELAY", &ad937x_ctrl::TX_ATTENUATION_DELAY)
+ .def_readonly("RX_GAIN_DELAY", &ad937x_ctrl::RX_GAIN_DELAY)
+ .def_readonly("FLASH_CAL", &ad937x_ctrl::FLASH_CAL)
+ .def_readonly("PATH_DELAY", &ad937x_ctrl::PATH_DELAY)
+ .def_readonly("TX_LO_LEAKAGE_INTERNAL", &ad937x_ctrl::TX_LO_LEAKAGE_INTERNAL)
+ .def_readonly("TX_LO_LEAKAGE_EXTERNAL", &ad937x_ctrl::TX_LO_LEAKAGE_EXTERNAL)
+ .def_readonly("TX_QEC_INIT", &ad937x_ctrl::TX_QEC_INIT)
+ .def_readonly("LOOPBACK_RX_LO_DELAY", &ad937x_ctrl::LOOPBACK_RX_LO_DELAY)
+ .def_readonly("LOOPBACK_RX_RX_QEC_INIT", &ad937x_ctrl::LOOPBACK_RX_RX_QEC_INIT)
+ .def_readonly("RX_LO_DELAY", &ad937x_ctrl::RX_LO_DELAY)
+ .def_readonly("RX_QEC_INIT", &ad937x_ctrl::RX_QEC_INIT)
+ .def_readonly("DPD_INIT", &ad937x_ctrl::DPD_INIT)
+ .def_readonly("CLGC_INIT", &ad937x_ctrl::CLGC_INIT)
+ .def_readonly("VSWR_INIT", &ad937x_ctrl::VSWR_INIT)
+ .def_readonly("TRACK_RX1_QEC", &ad937x_ctrl::TRACK_RX1_QEC)
+ .def_readonly("TRACK_RX2_QEC", &ad937x_ctrl::TRACK_RX2_QEC)
+ .def_readonly("TRACK_ORX1_QEC", &ad937x_ctrl::TRACK_ORX1_QEC)
+ .def_readonly("TRACK_ORX2_QEC", &ad937x_ctrl::TRACK_ORX2_QEC)
+ .def_readonly("TRACK_TX1_LOL", &ad937x_ctrl::TRACK_TX1_LOL)
+ .def_readonly("TRACK_TX2_LOL", &ad937x_ctrl::TRACK_TX2_LOL)
+ .def_readonly("TRACK_TX1_QEC", &ad937x_ctrl::TRACK_TX1_QEC)
+ .def_readonly("TRACK_TX2_QEC", &ad937x_ctrl::TRACK_TX2_QEC)
+ .def_readonly("TRACK_TX1_DPD", &ad937x_ctrl::TRACK_TX1_DPD)
+ .def_readonly("TRACK_TX2_DPD", &ad937x_ctrl::TRACK_TX2_DPD)
+ .def_readonly("TRACK_TX1_CLGC", &ad937x_ctrl::TRACK_TX1_CLGC)
+ .def_readonly("TRACK_TX2_CLGC", &ad937x_ctrl::TRACK_TX2_CLGC)
+ .def_readonly("TRACK_TX1_VSWR", &ad937x_ctrl::TRACK_TX1_VSWR)
+ .def_readonly("TRACK_TX2_VSWR", &ad937x_ctrl::TRACK_TX2_VSWR)
+ .def_readonly("TRACK_ORX1_QEC_SNLO", &ad937x_ctrl::TRACK_ORX1_QEC_SNLO)
+ .def_readonly("TRACK_ORX2_QEC_SNLO", &ad937x_ctrl::TRACK_ORX2_QEC_SNLO)
+ .def_readonly("TRACK_SRX_QEC", &ad937x_ctrl::TRACK_SRX_QEC)
+ .def_readonly("DEFAULT_INIT_CALS_MASKS", &ad937x_ctrl::DEFAULT_INIT_CALS_MASKS)
+ .def_readonly("DEFAULT_TRACKING_CALS_MASKS", &ad937x_ctrl::DEFAULT_TRACKING_CALS_MASKS)
+ .def_readonly("DEFAULT_INIT_CALS_TIMEOUT", &ad937x_ctrl::DEFAULT_INIT_CALS_TIMEOUT)
;
}
#endif
diff --git a/mpm/lib/mykonos/ad937x_ctrl.cpp b/mpm/lib/mykonos/ad937x_ctrl.cpp
index a3119cb89..0e76daac0 100644
--- a/mpm/lib/mykonos/ad937x_ctrl.cpp
+++ b/mpm/lib/mykonos/ad937x_ctrl.cpp
@@ -28,7 +28,64 @@
using namespace mpm::chips;
using namespace mpm::ad937x::device;
-
+//Init cals mask
+const uint32_t ad937x_ctrl::TX_BB_FILTER = ::TX_BB_FILTER;
+const uint32_t ad937x_ctrl::ADC_TUNER = ::ADC_TUNER;
+const uint32_t ad937x_ctrl::TIA_3DB_CORNER = ::TIA_3DB_CORNER;
+const uint32_t ad937x_ctrl::DC_OFFSET = ::DC_OFFSET;
+const uint32_t ad937x_ctrl::TX_ATTENUATION_DELAY = ::TX_ATTENUATION_DELAY;
+const uint32_t ad937x_ctrl::RX_GAIN_DELAY = ::RX_GAIN_DELAY;
+const uint32_t ad937x_ctrl::FLASH_CAL = ::FLASH_CAL;
+const uint32_t ad937x_ctrl::PATH_DELAY = ::PATH_DELAY;
+const uint32_t ad937x_ctrl::TX_LO_LEAKAGE_INTERNAL = ::TX_LO_LEAKAGE_INTERNAL;
+const uint32_t ad937x_ctrl::TX_LO_LEAKAGE_EXTERNAL = ::TX_LO_LEAKAGE_EXTERNAL;
+const uint32_t ad937x_ctrl::TX_QEC_INIT = ::TX_QEC_INIT;
+const uint32_t ad937x_ctrl::LOOPBACK_RX_LO_DELAY = ::LOOPBACK_RX_LO_DELAY;
+const uint32_t ad937x_ctrl::LOOPBACK_RX_RX_QEC_INIT = ::LOOPBACK_RX_RX_QEC_INIT;
+const uint32_t ad937x_ctrl::RX_LO_DELAY = ::RX_LO_DELAY;
+const uint32_t ad937x_ctrl::RX_QEC_INIT = ::RX_QEC_INIT;
+const uint32_t ad937x_ctrl::DPD_INIT = ::DPD_INIT;
+const uint32_t ad937x_ctrl::CLGC_INIT = ::CLGC_INIT;
+const uint32_t ad937x_ctrl::VSWR_INIT = ::VSWR_INIT;
+//Tracking Cals mask
+const uint32_t ad937x_ctrl::TRACK_RX1_QEC = ::TRACK_RX1_QEC;
+const uint32_t ad937x_ctrl::TRACK_RX2_QEC = ::TRACK_RX2_QEC;
+const uint32_t ad937x_ctrl::TRACK_ORX1_QEC = ::TRACK_ORX1_QEC;
+const uint32_t ad937x_ctrl::TRACK_ORX2_QEC = ::TRACK_ORX2_QEC;
+const uint32_t ad937x_ctrl::TRACK_TX1_LOL = ::TRACK_TX1_LOL;
+const uint32_t ad937x_ctrl::TRACK_TX2_LOL = ::TRACK_TX2_LOL;
+const uint32_t ad937x_ctrl::TRACK_TX1_QEC = ::TRACK_TX1_QEC;
+const uint32_t ad937x_ctrl::TRACK_TX2_QEC = ::TRACK_TX2_QEC;
+const uint32_t ad937x_ctrl::TRACK_TX1_DPD = ::TRACK_TX1_DPD;
+const uint32_t ad937x_ctrl::TRACK_TX2_DPD = ::TRACK_TX2_DPD;
+const uint32_t ad937x_ctrl::TRACK_TX1_CLGC = ::TRACK_TX1_CLGC;
+const uint32_t ad937x_ctrl::TRACK_TX2_CLGC = ::TRACK_TX2_CLGC;
+const uint32_t ad937x_ctrl::TRACK_TX1_VSWR = ::TRACK_TX1_VSWR;
+const uint32_t ad937x_ctrl::TRACK_TX2_VSWR = ::TRACK_TX2_VSWR;
+const uint32_t ad937x_ctrl::TRACK_ORX1_QEC_SNLO = ::TRACK_ORX1_QEC_SNLO;
+const uint32_t ad937x_ctrl::TRACK_ORX2_QEC_SNLO = ::TRACK_ORX2_QEC_SNLO;
+const uint32_t ad937x_ctrl::TRACK_SRX_QEC = ::TRACK_SRX_QEC;
+const uint32_t ad937x_ctrl::DEFAULT_INIT_CALS_MASKS =
+ ad937x_ctrl::TX_BB_FILTER |
+ ad937x_ctrl::ADC_TUNER |
+ ad937x_ctrl::TIA_3DB_CORNER |
+ ad937x_ctrl::DC_OFFSET |
+ ad937x_ctrl::TX_ATTENUATION_DELAY |
+ ad937x_ctrl::RX_GAIN_DELAY |
+ ad937x_ctrl::FLASH_CAL |
+ ad937x_ctrl::PATH_DELAY |
+ ad937x_ctrl::TX_LO_LEAKAGE_INTERNAL |
+ ad937x_ctrl::TX_QEC_INIT |
+ ad937x_ctrl::LOOPBACK_RX_LO_DELAY |
+ ad937x_ctrl::RX_QEC_INIT
+ ;
+const uint32_t ad937x_ctrl::DEFAULT_TRACKING_CALS_MASKS =
+ ad937x_ctrl::TRACK_RX1_QEC |
+ ad937x_ctrl::TRACK_RX2_QEC |
+ ad937x_ctrl::TRACK_TX1_QEC |
+ ad937x_ctrl::TRACK_TX2_QEC
+ ;
+const uint32_t ad937x_ctrl::DEFAULT_INIT_CALS_TIMEOUT = 60000;
static uhd::direction_t _get_direction_from_antenna(const std::string& antenna)
{
auto sub = antenna.substr(0, 2);
@@ -145,6 +202,11 @@ public:
device.finish_initialization();
}
+ virtual void setup_cal(uint32_t init_cals_mask, uint32_t tracking_cals_mask, uint32_t timeout)
+ {
+ std::lock_guard<std::mutex> lock(*spi_mutex);
+ device.setup_cal(init_cals_mask, tracking_cals_mask, timeout);
+ }
virtual void start_jesd_rx()
{
std::lock_guard<std::mutex> lock(*spi_mutex);
diff --git a/mpm/lib/mykonos/ad937x_device.cpp b/mpm/lib/mykonos/ad937x_device.cpp
index 2614be600..de3671849 100644
--- a/mpm/lib/mykonos/ad937x_device.cpp
+++ b/mpm/lib/mykonos/ad937x_device.cpp
@@ -19,7 +19,6 @@
#include "adi/mykonos.h"
#include "adi/mykonos_gpio.h"
#include "adi/mykonos_debug/mykonos_dbgjesd.h"
-
#include <boost/format.hpp>
#include <functional>
@@ -49,50 +48,6 @@ static const uint32_t AD9371_PRODUCT_ID = 0x3;
static const size_t ARM_BINARY_SIZE = 98304;
static const uint32_t PLL_LOCK_TIMEOUT_MS = 200;
-static const uint32_t INIT_CAL_TIMEOUT_MS = 10000;
-
-// TODO: actually figure out what cals we want to run
-// minimum required cals are 0x4F
-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 functions
@@ -318,8 +273,7 @@ ad937x_device::ad937x_device(
{
}
-void ad937x_device::_initialize_rf()
-{
+void ad937x_device::_setup_rf(){
// TODO: add setRfPllLoopFilter here
// Set frequencies
@@ -345,19 +299,21 @@ void ad937x_device::_initialize_rf()
set_gain(uhd::TX_DIRECTION, chain_t::ONE, TX_DEFAULT_GAIN);
set_gain(uhd::TX_DIRECTION, chain_t::TWO, TX_DEFAULT_GAIN);
- // Run and wait for init cals
- CALL_API(MYKONOS_runInitCals(mykonos_config.device, INIT_CALS));
+}
+
+void ad937x_device::setup_cal(uint32_t init_cals_mask, uint32_t tracking_cals_mask, uint32_t timeout){
+ // Run and wait for init cals
+ CALL_API(MYKONOS_runInitCals(mykonos_config.device, init_cals_mask));
uint8_t errorFlag = 0, errorCode = 0;
- CALL_API(MYKONOS_waitInitCals(mykonos_config.device, INIT_CAL_TIMEOUT_MS, &errorFlag, &errorCode));
+ CALL_API(MYKONOS_waitInitCals(mykonos_config.device, timeout, &errorFlag, &errorCode));
if ((errorFlag != 0) || (errorCode != 0))
{
throw mpm::runtime_error("Init cals failed!");
// TODO: add more debugging information here
}
-
- CALL_API(MYKONOS_enableTrackingCals(mykonos_config.device, TRACKING_CALS));
+ CALL_API(MYKONOS_enableTrackingCals(mykonos_config.device, tracking_cals_mask));
// ready for radioOn
}
@@ -389,9 +345,8 @@ void ad937x_device::finish_initialization()
// TODO: check ARM version before or after the load of the ARM
// currently binary has no readable version number until after it's loaded
-
- // TODO: separate initialize rf into its own step
- _initialize_rf();
+ //Run setup RF
+ _setup_rf();
}
void ad937x_device::start_jesd_tx()
diff --git a/mpm/lib/mykonos/ad937x_device.hpp b/mpm/lib/mykonos/ad937x_device.hpp
index 8ea0623a0..8dae6f2d3 100644
--- a/mpm/lib/mykonos/ad937x_device.hpp
+++ b/mpm/lib/mykonos/ad937x_device.hpp
@@ -54,6 +54,7 @@ public:
void begin_initialization();
void finish_initialization();
+ void setup_cal(uint32_t init_cals_mask, uint32_t tracking_cals_mask, uint32_t timeout);
void start_jesd_rx();
void start_jesd_tx();
void start_radio();
@@ -109,14 +110,13 @@ private:
ad937x_gain_ctrl_config_t gain_ctrl;
void _apply_gain_pins(uhd::direction_t direction, mpm::ad937x::device::chain_t chain);
-
+ void _setup_rf();
void _call_api_function(const std::function<mykonosErr_t()>& func);
void _call_gpio_api_function(const std::function<mykonosGpioErr_t()>& func);
std::string _get_arm_binary_path();
std::vector<uint8_t> _get_arm_binary();
- void _initialize_rf();
void _verify_product_id();
void _verify_multichip_sync_status(multichip_sync_t mcs);
diff --git a/mpm/python/usrp_mpm/dboard_manager/magnesium.py b/mpm/python/usrp_mpm/dboard_manager/magnesium.py
index 217517a56..d69b8ad23 100644
--- a/mpm/python/usrp_mpm/dboard_manager/magnesium.py
+++ b/mpm/python/usrp_mpm/dboard_manager/magnesium.py
@@ -508,7 +508,7 @@ class Magnesium(DboardManagerBase):
_sync_db_clock(self.clock_synchronizer)
# Clocks and PPS are now fully active!
- self.init_jesd(self.radio_regs)
+ self.init_jesd(self.radio_regs, args)
self.mykonos.start_radio()
return True
@@ -526,7 +526,24 @@ class Magnesium(DboardManagerBase):
self.cpld.poke16(addr, data)
return self.cpld.peek16(addr)
- def init_jesd(self, uio):
+ def init_rf_cal(self, args):
+ " Setup RF CAL "
+ self.log.info("Setting up RF CAL...")
+ try:
+ self._init_cals_mask = int(args.get('init_cals', str(self.mykonos.DEFAULT_INIT_CALS_MASKS)), 0)
+ self._tracking_cals_mask = int(args.get('tracking_cals', str(self.mykonos.DEFAULT_TRACKING_CALS_MASKS)), 0)
+ self._init_cals_timeout = int(args.get('init_cals_timeout', str(self.mykonos.DEFAULT_INIT_CALS_TIMEOUT)), 0)
+ except ValueError as ex:
+ self.log.warning("init() args missing or error using default value seeing following exception print out.")
+ self.log.warning("{}".format(ex))
+ self._init_cals_mask = self.mykonos.DEFAULT_INIT_CALS_MASKS
+ self._tracking_cals_mask = self.mykonos.DEFAULT_TRACKING_CALS_MASKS
+ self._init_cals_timeout = self.mykonos.DEFAULT_INIT_CALS_TIMEOUT
+ self.log.debug("args[init_cals]=0x{:02X}".format(self._init_cals_mask))
+ self.log.debug("args[tracking_cals]=0x{:02X}".format(self._tracking_cals_mask))
+ self.mykonos.setup_cal(self._init_cals_mask, self._tracking_cals_mask, self._init_cals_timeout)
+
+ def init_jesd(self, uio, args):
"""
Bring up the JESD link between Mykonos and the N310.
"""
@@ -546,6 +563,8 @@ class Magnesium(DboardManagerBase):
time.sleep(0.001)
self.jesdcore.send_sysref_pulse()
self.mykonos.finish_initialization()
+ # TODO:can we call this after JESD?
+ self.init_rf_cal(args)
self.log.trace("Starting JESD204b Link Initialization...")
# Generally, enable the source before the sink. Start with the DAC side.