aboutsummaryrefslogtreecommitdiffstats
path: root/host/tests/mb_controller_test.cpp
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2019-05-31 22:11:42 -0700
committerMartin Braun <martin.braun@ettus.com>2019-11-26 11:49:23 -0800
commitfaa4786e025e787c196eec99f213da0d51a1f87e (patch)
tree17e39f93b0251e6e87e25d37775f10e55c0119fe /host/tests/mb_controller_test.cpp
parent0200aedf4497d5bc4ddf9f3a071ed5395e605f2d (diff)
downloaduhd-faa4786e025e787c196eec99f213da0d51a1f87e.tar.gz
uhd-faa4786e025e787c196eec99f213da0d51a1f87e.tar.bz2
uhd-faa4786e025e787c196eec99f213da0d51a1f87e.zip
rfnoc: Add mb_controller API
The mb_controller is an interface to hardware-specific functions of the motherboard. The API works in two ways: - The user can request access to it, and thus interact directly with the motherboard - RFNoC blocks can request access to it, if they need to interact with the motherboard themselves.
Diffstat (limited to 'host/tests/mb_controller_test.cpp')
-rw-r--r--host/tests/mb_controller_test.cpp155
1 files changed, 155 insertions, 0 deletions
diff --git a/host/tests/mb_controller_test.cpp b/host/tests/mb_controller_test.cpp
new file mode 100644
index 000000000..48baadf29
--- /dev/null
+++ b/host/tests/mb_controller_test.cpp
@@ -0,0 +1,155 @@
+//
+// Copyright 2019 Ettus Research, a National Instruments Brand
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+//
+
+#include <uhd/rfnoc/mb_controller.hpp>
+#include <boost/test/unit_test.hpp>
+#include <iostream>
+
+using namespace uhd;
+using namespace uhd::rfnoc;
+
+class mock_timekeeper : public mb_controller::timekeeper
+{
+public:
+ uint64_t get_ticks_now() { return _ticks; }
+
+ uint64_t get_ticks_last_pps() { return _ticks; }
+
+ void set_ticks_now(const uint64_t ticks) { _ticks = ticks; }
+
+ void set_ticks_next_pps(const uint64_t ticks) { _ticks = ticks; }
+
+ uint64_t _ticks;
+ uint64_t _period;
+
+ void update_tick_rate(const double tick_rate)
+ {
+ set_tick_rate(tick_rate);
+ }
+
+private:
+ void set_period(const uint64_t period_ns) { _period = period_ns; }
+};
+
+class mock_mb_controller : public mb_controller
+{
+public:
+ mock_mb_controller()
+ {
+ auto tk = std::make_shared<mock_timekeeper>();
+ register_timekeeper(0, tk);
+ }
+
+ /**************************************************************************
+ * Motherboard Control API (see mb_controller.hpp)
+ *************************************************************************/
+ std::string get_mboard_name() const
+ {
+ return "MOCK-MB";
+ }
+
+ void set_time_source(const std::string& source)
+ {
+ time_source = source;
+ }
+
+ std::string get_time_source() const
+ {
+ return time_source;
+ }
+
+ std::vector<std::string> get_time_sources() const
+ {
+ return {"internal", "external"};
+ }
+
+ void set_clock_source(const std::string& source)
+ {
+ clock_source = source;
+ }
+
+ std::string get_clock_source() const
+ {
+ return clock_source;
+ }
+
+ std::vector<std::string> get_clock_sources() const
+ {
+ return {"internal", "external"};
+ }
+
+ void set_sync_source(
+ const std::string& /*clock_source*/, const std::string& /*time_source*/)
+ {
+ }
+
+ void set_sync_source(const device_addr_t& /*sync_source*/) {}
+
+ device_addr_t get_sync_source() const
+ {
+ return {};
+ }
+
+ std::vector<device_addr_t> get_sync_sources()
+ {
+ return {};
+ }
+
+ void set_clock_source_out(const bool enb)
+ {
+ clock_source_out = enb;
+ }
+
+ void set_time_source_out(const bool enb)
+ {
+ time_source_out = enb;
+ }
+
+ sensor_value_t get_sensor(const std::string& /*name*/)
+ {
+ return sensor_value_t("Ref", false, "locked", "unlocked");
+ }
+
+ std::vector<std::string> get_sensor_names()
+ {
+ return {"mock_sensor"};
+ }
+
+ uhd::usrp::mboard_eeprom_t get_eeprom()
+ {
+ return {};
+ }
+
+ std::string clock_source = "internal";
+ std::string time_source = "internal";
+ bool clock_source_out = false;
+ bool time_source_out = false;
+};
+
+BOOST_AUTO_TEST_CASE(test_mb_controller)
+{
+ auto mmbc = std::make_shared<mock_mb_controller>();
+
+ BOOST_REQUIRE_EQUAL(mmbc->get_num_timekeepers(), 1);
+ auto tk = mmbc->get_timekeeper(0);
+ auto tk_mock = std::dynamic_pointer_cast<mock_timekeeper>(tk);
+ BOOST_REQUIRE(tk);
+
+ constexpr double TICK_RATE = 200e6;
+ constexpr double PERIOD_NS = 5;
+ // This will call set_tick_rate() and thus set_period()
+ tk_mock->update_tick_rate(TICK_RATE);
+ BOOST_CHECK_EQUAL(tk->get_tick_rate(), TICK_RATE);
+ BOOST_CHECK_EQUAL(tk_mock->_period, PERIOD_NS * (uint64_t(1) << 32));
+
+ constexpr double TIME_0 = 1.0;
+ tk->set_time_now(uhd::time_spec_t(TIME_0));
+ BOOST_CHECK_EQUAL(tk->get_ticks_now(), TICK_RATE * TIME_0);
+ constexpr double TIME_1 = 0.5;
+ tk->set_time_next_pps(uhd::time_spec_t(TIME_1));
+ BOOST_CHECK_EQUAL(tk->get_ticks_last_pps(), TIME_1 * TICK_RATE);
+}
+