diff options
-rw-r--r-- | mpm/include/mpm/ad937x/ad937x_ctrl.hpp | 91 | ||||
-rw-r--r-- | mpm/lib/mykonos/ad937x_ctrl.cpp | 64 | ||||
-rw-r--r-- | mpm/lib/mykonos/ad937x_device.cpp | 65 | ||||
-rw-r--r-- | mpm/lib/mykonos/ad937x_device.hpp | 4 | ||||
-rw-r--r-- | mpm/python/usrp_mpm/dboard_manager/magnesium.py | 23 |
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. |