aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrung N Tran <trung.tran@ettus.com>2018-04-27 15:27:13 -0700
committerMartin Braun <martin.braun@ettus.com>2018-04-30 14:36:29 -0700
commit546aa04355ff34924ce1d00fd003cb0ee63c8cf9 (patch)
tree7922390d41b4dbc90c1bd71f763b42e05ca85b44
parent4e2fd551ad48e1ee13d2b7a203f624dd828c2c3b (diff)
downloaduhd-546aa04355ff34924ce1d00fd003cb0ee63c8cf9.tar.gz
uhd-546aa04355ff34924ce1d00fd003cb0ee63c8cf9.tar.bz2
uhd-546aa04355ff34924ce1d00fd003cb0ee63c8cf9.zip
mpm: replace long execution function with async call
- Replace mykonos finish_initialization with async version - Replace myknonos setup_cal with async version - Remove disable_timeout on rpc_server init()
-rw-r--r--mpm/include/mpm/ad937x/ad937x_ctrl.hpp47
-rw-r--r--mpm/lib/mykonos/adi_ctrl.cpp14
-rw-r--r--mpm/python/usrp_mpm/dboard_manager/magnesium.py15
-rw-r--r--mpm/python/usrp_mpm/mpmutils.py15
4 files changed, 76 insertions, 15 deletions
diff --git a/mpm/include/mpm/ad937x/ad937x_ctrl.hpp b/mpm/include/mpm/ad937x/ad937x_ctrl.hpp
index c7a31e92a..762bd2e0e 100644
--- a/mpm/include/mpm/ad937x/ad937x_ctrl.hpp
+++ b/mpm/include/mpm/ad937x/ad937x_ctrl.hpp
@@ -20,6 +20,7 @@
#include <functional>
#include <set>
#include <mutex>
+#include <future>
namespace mpm { namespace chips {
@@ -84,6 +85,10 @@ public:
static const uint32_t DEFAULT_TRACKING_CALS_MASKS;
static const uint32_t DEFAULT_INIT_CALS_TIMEOUT;
+ // Async call handles
+ std::future<void> handle_finish_initialization;
+ std::future<void> handle_setup_cal;
+
/*! \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
@@ -299,10 +304,48 @@ void export_mykonos(){
bp::class_<ad937x_ctrl, boost::noncopyable, std::shared_ptr<ad937x_ctrl>>("ad937x_ctrl", bp::no_init)
.def("set_master_clock_rate", &ad937x_ctrl::set_master_clock_rate)
.def("begin_initialization", &ad937x_ctrl::begin_initialization)
- .def("finish_initialization", &ad937x_ctrl::finish_initialization)
+ .def("async__finish_initialization", +[](
+ ad937x_ctrl& self
+ ){
+ self.handle_finish_initialization = std::async(std::launch::async,
+ &ad937x_ctrl::finish_initialization,
+ &self
+ );
+ })
+ .def("await__finish_initialization", +[](
+ ad937x_ctrl& self
+ )->bool{
+ if (self.handle_finish_initialization.wait_for(std::chrono::seconds(0)) == std::future_status::ready){
+ self.handle_finish_initialization.get();
+ return true;
+ }
+ return false;
+ })
.def("set_lo_source", &ad937x_ctrl::set_lo_source)
.def("get_lo_source", &ad937x_ctrl::get_lo_source)
- .def("setup_cal", &ad937x_ctrl::setup_cal)
+ .def("async__setup_cal", +[](
+ ad937x_ctrl& self,
+ const uint32_t init_cals_mask,
+ const uint32_t timeout,
+ const uint32_t tracking_cals_mask
+ ){
+ self.handle_setup_cal = std::async(std::launch::async,
+ &ad937x_ctrl::setup_cal,
+ &self,
+ init_cals_mask,
+ timeout,
+ tracking_cals_mask
+ );
+ })
+ .def("await__setup_cal", +[](
+ ad937x_ctrl& self
+ )->bool{
+ if (self.handle_setup_cal.wait_for(std::chrono::seconds(0)) == std::future_status::ready){
+ self.handle_setup_cal.get();
+ return true;
+ }
+ return false;
+ })
.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)
diff --git a/mpm/lib/mykonos/adi_ctrl.cpp b/mpm/lib/mykonos/adi_ctrl.cpp
index 5b2775ae0..2ae0ef663 100644
--- a/mpm/lib/mykonos/adi_ctrl.cpp
+++ b/mpm/lib/mykonos/adi_ctrl.cpp
@@ -278,13 +278,13 @@ commonErr_t CMB_writeToLog(
else {
mpm_log_level = mpm::types::log_level_t::TRACE;
}
-
- mpm::types::log_buf::make_singleton()->post(
- mpm_log_level,
- "AD937X",
- str(boost::format("[Device ID %d] [Error code: %d] %s")
- % int(deviceIndex) % errorCode % comment)
- );
+ //FIXME: This caused segfault with the async pattern call to c++ from boost python
+ // mpm::types::log_buf::make_singleton()->post(
+ // mpm_log_level,
+ // "AD937X",
+ // str(boost::format("[Device ID %d] [Error code: %d] %s")
+ // % int(deviceIndex) % errorCode % comment)
+ // );
return COMMONERR_OK;
}
diff --git a/mpm/python/usrp_mpm/dboard_manager/magnesium.py b/mpm/python/usrp_mpm/dboard_manager/magnesium.py
index 53341c206..2385b05eb 100644
--- a/mpm/python/usrp_mpm/dboard_manager/magnesium.py
+++ b/mpm/python/usrp_mpm/dboard_manager/magnesium.py
@@ -21,6 +21,7 @@ from usrp_mpm.dboard_manager.mg_periphs import TCA6408, MgCPLD
from usrp_mpm.dboard_manager.mg_periphs import DboardClockControl
from usrp_mpm.cores import nijesdcore
from usrp_mpm.mpmlog import get_logger
+from usrp_mpm.mpmutils import async_exec
from usrp_mpm.sys_utils.uio import open_uio
from usrp_mpm.sys_utils.udev import get_eeprom_paths
from usrp_mpm.cores import ClockSynchronizer
@@ -63,6 +64,7 @@ TRACKING_CALIBRATION_TABLE = {"TRACK_RX1_QEC" : 0x01,
"ALL" : 0xF3,
}
+
def create_spidev_iface_lmk(dev_node):
"""
Create a regs iface from a spidev node
@@ -513,9 +515,13 @@ class Magnesium(DboardManagerBase):
.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)
+ async_exec(
+ self.mykonos,
+ "setup_cal",
+ self._init_cals_mask,
+ self._tracking_cals_mask,
+ self._init_cals_timeout
+ )
def init_lo_source(self, args):
"""Set all LO
@@ -561,10 +567,9 @@ class Magnesium(DboardManagerBase):
jesdcore.send_sysref_pulse()
time.sleep(0.001) # 17us... ish.
jesdcore.send_sysref_pulse()
- self.mykonos.finish_initialization()
+ async_exec(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.
self.log.trace("Starting FPGA framer...")
diff --git a/mpm/python/usrp_mpm/mpmutils.py b/mpm/python/usrp_mpm/mpmutils.py
index 539cd8de4..151713988 100644
--- a/mpm/python/usrp_mpm/mpmutils.py
+++ b/mpm/python/usrp_mpm/mpmutils.py
@@ -8,7 +8,6 @@ Miscellaneous utilities for MPM
"""
import time
-import sys
def poll_with_timeout(state_check, timeout_ms, interval_ms):
"""
@@ -150,3 +149,17 @@ def str2bool(value):
except AttributeError:
return bool(value)
+
+def async_exec(parent, method_name, *args):
+ """Execute method_name asynchronously.
+ Requires the parent class to have this feature enabled.
+ """
+ async_name = 'async__' + method_name
+ await_name = 'await__' + method_name
+ # Spawn async
+ getattr(parent, async_name)(*args)
+ awaitable_method = getattr(parent, await_name)
+ # await
+ while not awaitable_method():
+ time.sleep(0.1)
+