aboutsummaryrefslogtreecommitdiffstats
path: root/mpm/include
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2017-04-25 17:00:34 -0700
committerMartin Braun <martin.braun@ettus.com>2017-12-22 15:03:52 -0800
commit151ba5fb06dfdb6fcc46ccfdabf5f1e064236981 (patch)
treefa941b0589b09a22957e8b7e3966679748a9b202 /mpm/include
parent1262dfb3ccf5a9916685b3399587593174c6583e (diff)
downloaduhd-151ba5fb06dfdb6fcc46ccfdabf5f1e064236981.tar.gz
uhd-151ba5fb06dfdb6fcc46ccfdabf5f1e064236981.tar.bz2
uhd-151ba5fb06dfdb6fcc46ccfdabf5f1e064236981.zip
mpm: Major refactoring
- Created clean interfaces for SPI and registers - Severed most links to UHD - Added a lockable class which allows exposing mutexes into Python
Diffstat (limited to 'mpm/include')
-rw-r--r--mpm/include/mpm/CMakeLists.txt7
-rw-r--r--mpm/include/mpm/ad937x/ad937x_ctrl.hpp18
-rw-r--r--mpm/include/mpm/ad937x/ad937x_spi_iface.hpp33
-rw-r--r--mpm/include/mpm/ad937x/adi_ctrl.hpp7
-rw-r--r--mpm/include/mpm/chips/CMakeLists.txt (renamed from mpm/include/mpm/lmk04828/CMakeLists.txt)0
-rw-r--r--mpm/include/mpm/chips/lmk04828_spi_iface.hpp33
-rw-r--r--mpm/include/mpm/dboards/magnesium_manager.hpp50
-rw-r--r--mpm/include/mpm/exception.hpp152
-rw-r--r--mpm/include/mpm/lmk04828/lmk04828_spi_iface.hpp42
-rw-r--r--mpm/include/mpm/spi/CMakeLists.txt3
-rw-r--r--mpm/include/mpm/spi/spi_iface.hpp53
-rw-r--r--mpm/include/mpm/spi/spi_regs_iface.hpp34
-rw-r--r--mpm/include/mpm/spi/spidev_iface.hpp92
-rw-r--r--mpm/include/mpm/types/CMakeLists.txt21
-rw-r--r--mpm/include/mpm/types/lockable.hpp51
-rw-r--r--mpm/include/mpm/types/regs_iface.hpp47
-rw-r--r--mpm/include/mpm/types/types_python.hpp36
17 files changed, 512 insertions, 167 deletions
diff --git a/mpm/include/mpm/CMakeLists.txt b/mpm/include/mpm/CMakeLists.txt
index a4ce92931..116899797 100644
--- a/mpm/include/mpm/CMakeLists.txt
+++ b/mpm/include/mpm/CMakeLists.txt
@@ -16,9 +16,12 @@
#
INSTALL(FILES
xbar_iface.hpp
+ exception.hpp
DESTINATION ${INCLUDE_DIR}/mpm
)
-ADD_SUBDIRECTORY(dboards)
-ADD_SUBDIRECTORY(lmk04828)
+
ADD_SUBDIRECTORY(ad937x)
+ADD_SUBDIRECTORY(chips)
+ADD_SUBDIRECTORY(dboards)
ADD_SUBDIRECTORY(spi)
+ADD_SUBDIRECTORY(types)
diff --git a/mpm/include/mpm/ad937x/ad937x_ctrl.hpp b/mpm/include/mpm/ad937x/ad937x_ctrl.hpp
index 995f4c379..4d47a631f 100644
--- a/mpm/include/mpm/ad937x/ad937x_ctrl.hpp
+++ b/mpm/include/mpm/ad937x/ad937x_ctrl.hpp
@@ -19,17 +19,21 @@
#include "ad937x_ctrl_types.hpp"
+#include <mpm/exception.hpp>
+#include <mpm/spi/spi_iface.hpp>
+
#include <uhd/types/direction.hpp>
#include <uhd/types/ranges.hpp>
-#include <uhd/exception.hpp>
-#include <uhd/types/serial.hpp>
#include <boost/noncopyable.hpp>
+
#include <memory>
#include <functional>
#include <set>
#include <mutex>
+namespace mpm { namespace chips {
+
/*! AD937x Control Interface
*
* A sane API for configuring AD937x chips.
@@ -58,7 +62,7 @@ public:
*/
static sptr make(
std::shared_ptr<std::mutex> spi_mutex,
- uhd::spi_iface::sptr iface,
+ mpm::types::regs_iface::sptr iface,
mpm::ad937x::gpio::gain_pins_t gain_pins);
virtual ~ad937x_ctrl(void) {}
@@ -141,7 +145,8 @@ public:
virtual double set_freq(const std::string &which, double value) = 0;
/*! \brief get the RF frequency for the direction specified in which
- /* Gets the RF frequency. This is a per direction setting.
+ *
+ * Returns the RF frequency. This is a per direction setting.
* \param which frontend string to specify direction to get
* \return actual frequency
*/
@@ -164,12 +169,13 @@ public:
virtual void set_gain_pin_step_sizes(const std::string &which, double inc_step, double dec_step) = 0;
};
+}}; /* namespace mpm::chips */
+
#ifdef LIBMPM_PYTHON
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)
- .def("make", &ad937x_ctrl::make)
.def("begin_initialization", &ad937x_ctrl::begin_initialization)
.def("finish_initialization", &ad937x_ctrl::finish_initialization)
.def("start_jesd_rx", &ad937x_ctrl::start_jesd_rx)
diff --git a/mpm/include/mpm/ad937x/ad937x_spi_iface.hpp b/mpm/include/mpm/ad937x/ad937x_spi_iface.hpp
new file mode 100644
index 000000000..85617c8ef
--- /dev/null
+++ b/mpm/include/mpm/ad937x/ad937x_spi_iface.hpp
@@ -0,0 +1,33 @@
+//
+// Copyright 2017 Ettus Research (National Instruments)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#pragma once
+
+#include <mpm/types/regs_iface.hpp>
+
+namespace mpm { namespace chips {
+
+ /*! Return a peek/poke interface to the LMK04828
+ *
+ * Assumption is it is attached to a spidev
+ */
+ mpm::types::regs_iface::sptr make_ad937x_iface(
+ const std::string &spi_device
+ );
+
+}}; /* namespace mpm::chips */
+
diff --git a/mpm/include/mpm/ad937x/adi_ctrl.hpp b/mpm/include/mpm/ad937x/adi_ctrl.hpp
index 34d9d891c..eef71c5bf 100644
--- a/mpm/include/mpm/ad937x/adi_ctrl.hpp
+++ b/mpm/include/mpm/ad937x/adi_ctrl.hpp
@@ -17,8 +17,7 @@
#pragma once
-#include <uhd/types/serial.hpp>
-
+#include <mpm/types/regs_iface.hpp>
#include <chrono>
struct ad9371_spiSettings_t
@@ -27,12 +26,12 @@ struct ad9371_spiSettings_t
return reinterpret_cast<ad9371_spiSettings_t *>(sps);
}
- explicit ad9371_spiSettings_t(uhd::spi_iface* uhd_iface);
+ explicit ad9371_spiSettings_t(mpm::types::regs_iface*);
// spiSetting_t MUST be the first data member so that the
// reinterpret_cast in make() works
spiSettings_t spi_settings;
- uhd::spi_iface* spi_iface;
+ mpm::types::regs_iface* spi_iface;
std::chrono::time_point<std::chrono::steady_clock> timeout_start;
std::chrono::microseconds timeout_duration;
};
diff --git a/mpm/include/mpm/lmk04828/CMakeLists.txt b/mpm/include/mpm/chips/CMakeLists.txt
index 35df8d624..35df8d624 100644
--- a/mpm/include/mpm/lmk04828/CMakeLists.txt
+++ b/mpm/include/mpm/chips/CMakeLists.txt
diff --git a/mpm/include/mpm/chips/lmk04828_spi_iface.hpp b/mpm/include/mpm/chips/lmk04828_spi_iface.hpp
new file mode 100644
index 000000000..ae897f02f
--- /dev/null
+++ b/mpm/include/mpm/chips/lmk04828_spi_iface.hpp
@@ -0,0 +1,33 @@
+//
+// Copyright 2017 Ettus Research (National Instruments)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#pragma once
+
+#include <mpm/types/regs_iface.hpp>
+
+namespace mpm { namespace chips {
+
+ /*! Return a peek/poke interface to the LMK04828
+ *
+ * Assumption is it is attached to a spidev
+ */
+ mpm::types::regs_iface::sptr make_lmk04828_iface(
+ const std::string &spi_device
+ );
+
+}}; /* namespace mpm::chips */
+
diff --git a/mpm/include/mpm/dboards/magnesium_manager.hpp b/mpm/include/mpm/dboards/magnesium_manager.hpp
index 34c81292e..beb5a3cc2 100644
--- a/mpm/include/mpm/dboards/magnesium_manager.hpp
+++ b/mpm/include/mpm/dboards/magnesium_manager.hpp
@@ -17,43 +17,53 @@
#pragma once
-#include "mpm/spi/spidev_iface.hpp"
-#include "mpm/lmk04828/lmk04828_spi_iface.hpp"
-#include "mpm/ad937x/ad937x_ctrl.hpp"
+#include <mpm/types/lockable.hpp>
+#include <mpm/types/regs_iface.hpp>
+#include <mpm/ad937x/ad937x_ctrl.hpp>
#include <memory>
+#include <mutex>
namespace mpm { namespace dboards {
- class magnesium_periph_manager// : public dboard_periph_manager
+ class magnesium_manager// : public dboard_periph_manager
{
public:
- magnesium_periph_manager(std::string lmk_spidev, std::string mykonos_spidev);
+ magnesium_manager(
+ const std::string &lmk_spidev,
+ const std::string &mykonos_spidev
+ );
- /*! Return a reference to the clock chip
+ /*! Return a reference to the SPI mutex
*/
- lmk04828_iface::sptr get_clock_ctrl(){return _clock_ctrl;};
+ mpm::types::lockable::sptr get_spi_lock() { return _spi_lock; }
- /*! Return a reference to the radio chip
+ /*! Return a reference to the clock chip controls
*/
- ad937x_ctrl::sptr get_radio_ctrl(){return _mykonos_ctrl;};
+ mpm::types::regs_iface::sptr get_clock_ctrl(){ return _clock_ctrl; }
+
+ /*! Return a reference to the radio chip controls
+ */
+ mpm::chips::ad937x_ctrl::sptr get_radio_ctrl(){ return _mykonos_ctrl; }
private:
- //cpld control
std::shared_ptr<std::mutex> _spi_mutex;
- lmk04828_spi_iface::sptr _clock_spi;
- lmk04828_iface::sptr _clock_ctrl;
- mpm::spi::spidev_iface::sptr _mykonos_spi;
- ad937x_ctrl::sptr _mykonos_ctrl;
- };
-}};
+ // TODO: cpld control
+
+ mpm::types::lockable::sptr _spi_lock;
+ mpm::types::regs_iface::sptr _clock_ctrl;
+ mpm::chips::ad937x_ctrl::sptr _mykonos_ctrl;
+ };
+}}; /* namespace mpm::dboards */
#ifdef LIBMPM_PYTHON
-void export_dboards(){
+void export_magnesium(){
LIBMPM_BOOST_PREAMBLE("dboards")
- bp::class_<mpm::dboards::magnesium_periph_manager>("magnesium_periph_manager", bp::init<std::string, std::string>())
- .def("get_clock_ctrl", &mpm::dboards::magnesium_periph_manager::get_clock_ctrl)
- .def("get_radio_ctrl", &mpm::dboards::magnesium_periph_manager::get_radio_ctrl)
+ using namespace mpm::dboards;
+ bp::class_<mpm::dboards::magnesium_manager>("magnesium_manager", bp::init<std::string, std::string>())
+ .def("get_spi_lock", &mpm::dboards::magnesium_manager::get_spi_lock)
+ .def("get_clock_ctrl", &mpm::dboards::magnesium_manager::get_clock_ctrl)
+ .def("get_radio_ctrl", &mpm::dboards::magnesium_manager::get_radio_ctrl)
;
}
#endif
diff --git a/mpm/include/mpm/exception.hpp b/mpm/include/mpm/exception.hpp
new file mode 100644
index 000000000..3e06ae0d4
--- /dev/null
+++ b/mpm/include/mpm/exception.hpp
@@ -0,0 +1,152 @@
+//
+// Copyright 2017 Ettus Research (National Instruments Corp.)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#pragma once
+
+#include <stdexcept>
+#include <string>
+
+namespace mpm {
+
+ struct exception : std::runtime_error{
+ exception(const std::string &what);
+ virtual unsigned code(void) const = 0;
+ virtual exception *dynamic_clone(void) const = 0;
+ virtual void dynamic_throw(void) const = 0;
+ };
+
+ struct assertion_error : exception{
+ assertion_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual assertion_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ struct lookup_error : exception{
+ lookup_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual lookup_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ struct index_error : lookup_error{
+ index_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual index_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ struct key_error : lookup_error{
+ key_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual key_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ struct type_error : exception{
+ type_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual type_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ struct value_error : exception{
+ value_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual value_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ struct runtime_error : exception{
+ runtime_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual runtime_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ struct not_implemented_error : runtime_error{
+ not_implemented_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual not_implemented_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ struct environment_error : exception{
+ environment_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual environment_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ struct io_error : environment_error{
+ io_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual io_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ struct os_error : environment_error{
+ os_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual os_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ struct system_error : exception{
+ system_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual system_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ struct syntax_error : exception{
+ syntax_error(const std::string &what);
+ virtual unsigned code(void) const;
+ virtual syntax_error *dynamic_clone(void) const;
+ virtual void dynamic_throw(void) const;
+ };
+
+ /*!
+ * Create a formatted string with throw-site information.
+ * Fills in the function name, file name, and line number.
+ * \param what the std::exception message
+ * \return the formatted exception message
+ */
+ #define MPM_THROW_SITE_INFO(what) std::string( \
+ std::string(what) + "\n" + \
+ " in " + std::string(__PRETTY_FUNCTION__) + "\n" + \
+ " at " + std::string(__FILE__) + ":" + BOOST_STRINGIZE(__LINE__) + "\n" \
+ )
+
+ /*!
+ * Throws an invalid code path exception with throw-site information.
+ * Use this macro in places that code execution is not supposed to go.
+ */
+ #define MPM_THROW_INVALID_CODE_PATH() \
+ throw mpm::system_error(MPM_THROW_SITE_INFO("invalid code path"))
+
+ /*!
+ * Assert the result of the code evaluation.
+ * If the code evaluates to false, throw an assertion error.
+ * \param code the code that resolved to a boolean
+ */
+ #define MPM_ASSERT_THROW(code) {if (not (code)) \
+ throw mpm::assertion_error(MPM_THROW_SITE_INFO(#code)); \
+ }
+
+} /* namespace mpm */
+
diff --git a/mpm/include/mpm/lmk04828/lmk04828_spi_iface.hpp b/mpm/include/mpm/lmk04828/lmk04828_spi_iface.hpp
deleted file mode 100644
index 4fe124298..000000000
--- a/mpm/include/mpm/lmk04828/lmk04828_spi_iface.hpp
+++ /dev/null
@@ -1,42 +0,0 @@
-#pragma once
-
-#include "lmk04828.hpp"
-#include "uhd/types/serial.hpp"
-#include <boost/shared_ptr.hpp>
-
-class lmk04828_spi_iface
-{
-public:
- using sptr = boost::shared_ptr<lmk04828_spi_iface>;
- lmk04828_spi_iface(uhd::spi_iface::sptr iface);
- lmk04828_iface::write_fn_t get_write_fn();
- lmk04828_iface::read_fn_t get_read_fn();
- static sptr make(uhd::spi_iface::sptr iface);
-
-private:
- const int LMK_SPI_NUM_BITS = 24;
- const int LMK_SPI_READ_FLAG = 1;
- const int LMK_SPI_READ_FLAG_OFFSET = 23;
- const int LMK_SPI_READ_ADDR_OFFSET = 8;
- const int LMK_SPI_RESERVED_FIELD_MASK = ~(0x3 << 21);
- const int DEFAULT_SLAVE = 1;
-
- uhd::spi_iface::sptr _spi_iface;
- uhd::spi_config_t config;
-
- void spi_write(std::vector<uint32_t> writes);
- uint8_t spi_read(uint32_t addr);
-};
-
-#ifdef LIBMPM_PYTHON
-void export_lmk(){
- LIBMPM_BOOST_PREAMBLE("lmk04828")
- bp::class_<lmk04828_iface, boost::shared_ptr<lmk04828_iface>, boost::noncopyable >("lmk04828_iface", bp::no_init)
- .def("verify_chip_id", &lmk04828_iface::verify_chip_id)
- .def("get_chip_id", &lmk04828_iface::get_chip_id)
- .def("init", &lmk04828_iface::init)
- .def("enable_sysref_pulse", &lmk04828_iface::enable_sysref_pulse)
- ;
-}
-// .def("make", &lmk04828_iface::make)
-#endif
diff --git a/mpm/include/mpm/spi/CMakeLists.txt b/mpm/include/mpm/spi/CMakeLists.txt
index 0833764ff..0413c3e04 100644
--- a/mpm/include/mpm/spi/CMakeLists.txt
+++ b/mpm/include/mpm/spi/CMakeLists.txt
@@ -16,6 +16,7 @@
#
INSTALL(FILES
- spidev_iface.hpp
+ spi_iface.hpp
+ spi_regs_iface.hpp
DESTINATION ${INCLUDE_DIR}/mpm/spi
)
diff --git a/mpm/include/mpm/spi/spi_iface.hpp b/mpm/include/mpm/spi/spi_iface.hpp
new file mode 100644
index 000000000..8f8eaa2ec
--- /dev/null
+++ b/mpm/include/mpm/spi/spi_iface.hpp
@@ -0,0 +1,53 @@
+//
+// Copyright 2017 Ettus Research (National Instruments)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#pragma once
+
+#include <memory>
+#include <string>
+
+namespace mpm { namespace spi {
+
+ /*! Implementation of a uhd::spi_iface that uses Linux' spidev underneath.
+ */
+ class spi_iface
+ {
+ public:
+ using sptr = std::shared_ptr<spi_iface>;
+
+ /*! Convenience function: SPI xfer is 24 bits write, 8 bits read.
+ *
+ * \param data The write data for this xfer
+ *
+ * \return 8 bits worth of the return xfer
+ */
+ virtual uint32_t transfer24_8(
+ const uint32_t data
+ ) = 0;
+
+ /*!
+ * \param device The path to the spidev used (e.g. "/dev/spidev0.0")
+ * \param speed_hz Transaction speed in Hz
+ */
+ static sptr make_spidev(
+ const std::string &device,
+ const int speed_hz
+ );
+ };
+
+}}; /* namespace mpm */
+
diff --git a/mpm/include/mpm/spi/spi_regs_iface.hpp b/mpm/include/mpm/spi/spi_regs_iface.hpp
new file mode 100644
index 000000000..87f398db1
--- /dev/null
+++ b/mpm/include/mpm/spi/spi_regs_iface.hpp
@@ -0,0 +1,34 @@
+//
+// Copyright 2017 Ettus Research (National Instruments)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#pragma once
+
+#include <mpm/types/regs_iface.hpp>
+#include <mpm/spi/spi_iface.hpp>
+
+namespace mpm { namespace spi {
+
+ mpm::types::regs_iface::sptr make_spi_regs_iface(
+ mpm::spi::spi_iface::sptr spi_iface,
+ uint32_t addr_shift,
+ uint32_t data_shift,
+ uint32_t read_flags,
+ uint32_t write_flags = 0
+ );
+
+}}; /* namespace mpm::spi */
+
diff --git a/mpm/include/mpm/spi/spidev_iface.hpp b/mpm/include/mpm/spi/spidev_iface.hpp
deleted file mode 100644
index ef5303f7b..000000000
--- a/mpm/include/mpm/spi/spidev_iface.hpp
+++ /dev/null
@@ -1,92 +0,0 @@
-//
-// Copyright 2017 Ettus Research (National Instruments)
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-//
-
-#pragma once
-
-#include "uhd/types/serial.hpp"
-#include <boost/shared_ptr.hpp>
-
-namespace mpm { namespace spi {
-
- /*! Implementation of a uhd::spi_iface that uses Linux' spidev underneath.
- */
- class spidev_iface : public uhd::spi_iface
- {
- public:
- typedef boost::shared_ptr<spidev_iface> sptr;
- virtual uint32_t read_spi(
- int which_slave,
- const uhd::spi_config_t &config,
- uint32_t data,
- size_t num_bits
- ) = 0;
-
- virtual void write_spi(
- int which_slave,
- const uhd::spi_config_t &config,
- uint32_t data,
- size_t num_bits
- ) = 0;
-
- virtual uint32_t transact_spi(
- int /* which_slave */,
- const uhd::spi_config_t & /* config */,
- uint32_t data,
- size_t num_bits,
- bool readback
- ) = 0;
- /*!
- * \param device The path to the spidev used.
- */
- static sptr make(const std::string &device);
- };
-
-}}; /* namespace mpm */
-
-//void export_spi(){
- //// Register submodule spi
- //bp::object spi_module(bp::handle<>(bp::borrowed(PyImport_AddModule("libpyusrp_periphs.spi"))));
- //bp::scope().attr("spi") = spi_module;
- //bp::scope io_scope = spi_module;
-
- //bp::class_<spi_lock, boost::noncopyable, boost::shared_ptr<spi_lock> >("spi_lock", bp::no_init)
- //.def("make", &spi_lock::make)
- //.def("get_spidev", &spi_lock::get_spidev)
- //;
-
- //bp::class_<mpm::spi_iface, boost::noncopyable>("spi_iface", bp::no_init)
- //.def("write_byte", &mpm::spi_iface::write_byte)
- //.def("write_bytes", &mpm::spi_iface::write_bytes)
- //.def("read_byte", &mpm::spi_iface::read_byte)
- //.def("write_field", &mpm::spi_iface::write_field)
- //.def("read_field", &mpm::spi_iface::read_field)
- //.def("get_wire_mode", &mpm::spi_iface::get_wire_mode)
- //.def("get_endianness", &mpm::spi_iface::get_endianness)
- //.def("get_chip_select", &mpm::spi_iface::get_chip_select)
- //;
-
- //bp::enum_<mpm::spi_iface::spi_endianness_t>("spi_endianness")
- //.value("lsb_first", mpm::spi_iface::spi_endianness_t::LSB_FIRST)
- //.value("msb_first", mpm::spi_iface::spi_endianness_t::MSB_FIRST)
- //;
-
- //bp::enum_<mpm::spi_iface::spi_wire_mode_t>("spi_wire_mode")
- //.value("three_wire_mode", mpm::spi_iface::spi_wire_mode_t::THREE_WIRE_MODE)
- //.value("four_wire_mode", mpm::spi_iface::spi_wire_mode_t::FOUR_WIRE_MODE)
- //;
-//}
-
diff --git a/mpm/include/mpm/types/CMakeLists.txt b/mpm/include/mpm/types/CMakeLists.txt
new file mode 100644
index 000000000..a74a92519
--- /dev/null
+++ b/mpm/include/mpm/types/CMakeLists.txt
@@ -0,0 +1,21 @@
+#
+# Copyright 2017 Ettus Research (National Instruments)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+INSTALL(FILES
+ regs_iface.hpp
+ DESTINATION ${INCLUDE_DIR}/mpm/types
+)
diff --git a/mpm/include/mpm/types/lockable.hpp b/mpm/include/mpm/types/lockable.hpp
new file mode 100644
index 000000000..70e694be6
--- /dev/null
+++ b/mpm/include/mpm/types/lockable.hpp
@@ -0,0 +1,51 @@
+//
+// Copyright 2017 Ettus Research (National Instruments)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#pragma once
+
+#include <boost/noncopyable.hpp>
+#include <memory>
+#include <mutex>
+
+namespace mpm { namespace types {
+
+ /*! A lockable object
+ *
+ * Don't tell anyone, but's really just a wrapper around a mutex. This
+ * class is primarily to make it easy to safely expose that mutex into
+ * Python.
+ */
+ class lockable : public boost::noncopyable
+ {
+ public:
+ using sptr = std::shared_ptr<lockable>;
+
+ /*! Lock the lock
+ */
+ virtual void lock() = 0;
+
+ /*! Unlock the lock
+ */
+ virtual void unlock() = 0;
+
+ static sptr make(
+ std::shared_ptr<std::mutex> spi_mutex
+ );
+ };
+
+}}; /* namespace mpm::types */
+
diff --git a/mpm/include/mpm/types/regs_iface.hpp b/mpm/include/mpm/types/regs_iface.hpp
new file mode 100644
index 000000000..78e590b23
--- /dev/null
+++ b/mpm/include/mpm/types/regs_iface.hpp
@@ -0,0 +1,47 @@
+//
+// Copyright 2017 Ettus Research (National Instruments)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#pragma once
+
+#include <boost/noncopyable.hpp>
+#include <memory>
+
+namespace mpm { namespace types {
+
+ /*! Interface to a register reader/writer interface
+ */
+ class regs_iface : public boost::noncopyable
+ {
+ public:
+ using sptr = std::shared_ptr<regs_iface>;
+
+ /*! Return an 8-bit value from a given address
+ */
+ virtual uint8_t peek8(
+ const uint32_t addr
+ ) = 0;
+
+ /*! Write an 8-bit value to a given address
+ */
+ virtual void poke8(
+ const uint32_t addr,
+ const uint8_t data
+ ) = 0;
+ };
+
+}}; /* namespace mpm::regs */
+
diff --git a/mpm/include/mpm/types/types_python.hpp b/mpm/include/mpm/types/types_python.hpp
new file mode 100644
index 000000000..a0a00aa48
--- /dev/null
+++ b/mpm/include/mpm/types/types_python.hpp
@@ -0,0 +1,36 @@
+//
+// Copyright 2017 Ettus Research (National Instruments)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#pragma once
+
+#include "lockable.hpp"
+#include "regs_iface.hpp"
+
+void export_types() {
+ LIBMPM_BOOST_PREAMBLE("types")
+ using namespace mpm::types;
+ bp::class_<lockable, boost::noncopyable, std::shared_ptr<lockable> >("lockable", bp::no_init)
+ .def("lock", &lockable::lock)
+ .def("unlock", &lockable::unlock)
+ ;
+
+ bp::class_<regs_iface, boost::noncopyable, std::shared_ptr<regs_iface> >("regs_iface", bp::no_init)
+ .def("peek8", &regs_iface::peek8)
+ .def("poke8", &regs_iface::poke8)
+ ;
+}
+