aboutsummaryrefslogtreecommitdiffstats
path: root/host/tests/mb_controller_test.cpp
blob: 30b9f64f384fec1d691dc1408eaf79457b317772 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
//
// Copyright 2019 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: GPL-3.0-or-later
//

#include <uhd/rfnoc/mb_controller.hpp>
#include <uhdlib/features/discoverable_feature_registry.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() override
    {
        return _ticks;
    }

    uint64_t get_ticks_last_pps() override
    {
        return _ticks;
    }

    void set_ticks_now(const uint64_t ticks) override
    {
        _ticks = ticks;
    }

    void set_ticks_next_pps(const uint64_t ticks) override
    {
        _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) override
    {
        _period = period_ns;
    }
};

class mock_mb_controller : public mb_controller,
                           public ::uhd::features::discoverable_feature_registry
{
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 override
    {
        return "MOCK-MB";
    }

    void set_time_source(const std::string& source) override
    {
        time_source = source;
    }

    std::string get_time_source() const override
    {
        return time_source;
    }

    std::vector<std::string> get_time_sources() const override
    {
        return {"internal", "external"};
    }

    void set_clock_source(const std::string& source) override
    {
        clock_source = source;
    }

    std::string get_clock_source() const override
    {
        return clock_source;
    }

    std::vector<std::string> get_clock_sources() const override
    {
        return {"internal", "external"};
    }

    void set_sync_source(
        const std::string& /*clock_source*/, const std::string& /*time_source*/) override
    {
    }

    void set_sync_source(const device_addr_t& /*sync_source*/) override {}

    device_addr_t get_sync_source() const override
    {
        return {};
    }

    std::vector<device_addr_t> get_sync_sources() override
    {
        return {};
    }

    void set_clock_source_out(const bool enb) override
    {
        clock_source_out = enb;
    }

    void set_time_source_out(const bool enb) override
    {
        time_source_out = enb;
    }

    sensor_value_t get_sensor(const std::string& /*name*/) override
    {
        return sensor_value_t("Ref", false, "locked", "unlocked");
    }

    std::vector<std::string> get_sensor_names() override
    {
        return {"mock_sensor"};
    }

    uhd::usrp::mboard_eeprom_t get_eeprom() override
    {
        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);
}