diff options
| -rw-r--r-- | mpm/include/mpm/ad937x/ad937x_ctrl.hpp | 47 | ||||
| -rw-r--r-- | mpm/lib/mykonos/adi_ctrl.cpp | 14 | ||||
| -rw-r--r-- | mpm/python/usrp_mpm/dboard_manager/magnesium.py | 15 | ||||
| -rw-r--r-- | mpm/python/usrp_mpm/mpmutils.py | 15 | 
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) +  | 
