aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/x400/x400_radio_control.hpp
blob: 8848926c7d0dedc4d9204d73450c4cbc1a59d0b2 (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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
//
// Copyright 2020 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: GPL-3.0-or-later
//

#pragma once

#include "adc_self_calibration.hpp"
#include <uhd/rfnoc/noc_block_base.hpp>
#include <uhd/types/device_addr.hpp>
#include <uhd/types/direction.hpp>
#include <uhd/types/ranges.hpp>
#include <uhdlib/features/fpga_load_notification_iface.hpp>
#include <uhdlib/rfnoc/radio_control_impl.hpp>
#include <uhdlib/rfnoc/rf_control/dboard_iface.hpp>
#include <uhdlib/usrp/common/mpmd_mb_controller.hpp>
#include <uhdlib/usrp/common/rpc.hpp>
#include <uhdlib/usrp/common/x400_rfdc_control.hpp>
#include <uhdlib/utils/rpc.hpp>
#include <stddef.h>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
#include <uhdlib/usrp/cores/gpio_atr_3000.hpp>
#include "x400_gpio_control.hpp"

namespace uhd { namespace rfnoc {

namespace x400_regs {

//! Base address for the rf_timing_control module. This controls the NCOs and
// other things in the RFDC.
constexpr uint32_t RFDC_CTRL_BASE = radio_control_impl::regmap::PERIPH_BASE + 0x8000;

} // namespace x400_regs

class x400_radio_control_impl : public radio_control_impl
{
public:
    using sptr = std::shared_ptr<x400_radio_control_impl>;

    /************************************************************************
     * Structors
     ***********************************************************************/
    x400_radio_control_impl(make_args_ptr make_args);
    virtual ~x400_radio_control_impl() = default;

    std::string get_slot_name() const override
    {
        return _radio_slot;
    }

    size_t get_chan_from_dboard_fe(const std::string&, uhd::direction_t) const override;
    std::string get_dboard_fe_from_chan(size_t chan, uhd::direction_t) const override;

    uhd::eeprom_map_t get_db_eeprom() override;

    // GPIO methods
    std::vector<std::string> get_gpio_banks() const override;
    uint32_t get_gpio_attr(const std::string& bank, const std::string& attr) override;
    void set_gpio_attr(
        const std::string& bank, const std::string& attr, const uint32_t value) override;

    // Shim calls for every method in rf_control_core
    double set_rate(const double rate) override;
    std::string get_tx_antenna(const size_t chan) const override;
    std::vector<std::string> get_tx_antennas(const size_t chan) const override;
    void set_tx_antenna(const std::string& ant, const size_t chan) override;
    std::string get_rx_antenna(const size_t chan) const override;
    std::vector<std::string> get_rx_antennas(const size_t chan) const override;
    void set_rx_antenna(const std::string& ant, const size_t chan) override;
    double get_tx_frequency(const size_t chan) override;
    double set_tx_frequency(const double freq, size_t chan) override;
    void set_tx_tune_args(const uhd::device_addr_t& args, const size_t chan) override;
    uhd::freq_range_t get_tx_frequency_range(const size_t chan) const override;
    double get_rx_frequency(const size_t chan) override;
    double set_rx_frequency(const double freq, const size_t chan) override;
    void set_rx_tune_args(const uhd::device_addr_t& args, const size_t chan) override;
    uhd::freq_range_t get_rx_frequency_range(const size_t chan) const override;
    std::vector<std::string> get_tx_gain_names(const size_t chan) const override;
    uhd::gain_range_t get_tx_gain_range(const size_t chan) const override;
    uhd::gain_range_t get_tx_gain_range(
        const std::string& name, const size_t chan) const override;
    double get_tx_gain(const size_t chan) override;
    double get_tx_gain(const std::string& name, const size_t chan) override;
    double set_tx_gain(const double gain, const size_t chan) override;
    double set_tx_gain(
        const double gain, const std::string& name, const size_t chan) override;
    std::vector<std::string> get_rx_gain_names(const size_t chan) const override;
    uhd::gain_range_t get_rx_gain_range(const size_t chan) const override;
    uhd::gain_range_t get_rx_gain_range(
        const std::string& name, const size_t chan) const override;
    double get_rx_gain(const size_t chan) override;
    double get_rx_gain(const std::string& name, const size_t chan) override;
    double set_rx_gain(const double gain, const size_t chan) override;
    double set_rx_gain(
        const double gain, const std::string& name, const size_t chan) override;
    void set_rx_agc(const bool enable, const size_t chan) override;
    meta_range_t get_tx_bandwidth_range(size_t chan) const override;
    double get_tx_bandwidth(const size_t chan) override;
    double set_tx_bandwidth(const double bandwidth, const size_t chan) override;
    meta_range_t get_rx_bandwidth_range(size_t chan) const override;
    double get_rx_bandwidth(const size_t chan) override;
    double set_rx_bandwidth(const double bandwidth, const size_t chan) override;

    std::vector<std::string> get_rx_lo_names(const size_t chan) const override;
    std::vector<std::string> get_rx_lo_sources(
        const std::string& name, const size_t chan) const override;
    freq_range_t get_rx_lo_freq_range(
        const std::string& name, const size_t chan) const override;
    void set_rx_lo_source(
        const std::string& src, const std::string& name, const size_t chan) override;
    const std::string get_rx_lo_source(
        const std::string& name, const size_t chan) override;
    void set_rx_lo_export_enabled(
        bool enabled, const std::string& name, const size_t chan) override;
    bool get_rx_lo_export_enabled(
        const std::string& name, const size_t chan) override;
    double set_rx_lo_freq(
        double freq, const std::string& name, const size_t chan) override;
    double get_rx_lo_freq(const std::string& name, const size_t chan) override;
    std::vector<std::string> get_tx_lo_names(const size_t chan) const override;
    std::vector<std::string> get_tx_lo_sources(
        const std::string& name, const size_t chan) const override;
    freq_range_t get_tx_lo_freq_range(
        const std::string& name, const size_t chan) override;
    void set_tx_lo_source(
        const std::string& src, const std::string& name, const size_t chan) override;
    const std::string get_tx_lo_source(
        const std::string& name, const size_t chan) override;
    void set_tx_lo_export_enabled(
        const bool enabled, const std::string& name, const size_t chan) override;
    bool get_tx_lo_export_enabled(const std::string& name, const size_t chan) override;
    double set_tx_lo_freq(
        const double freq, const std::string& name, const size_t chan) override;
    double get_tx_lo_freq(const std::string& name, const size_t chan) override;
    std::vector<std::string> get_rx_sensor_names(size_t chan) const override;
    uhd::sensor_value_t get_rx_sensor(const std::string& name, size_t chan) override;
    std::vector<std::string> get_tx_sensor_names(size_t chan) const override;
    uhd::sensor_value_t get_tx_sensor(const std::string& name, size_t chan) override;

    void set_command_time(uhd::time_spec_t time, const size_t chan) override;

    // Non-API methods
    // This is used for x4xx radio block unit tests
    std::vector<uhd::usrp::pwr_cal_mgr::sptr> get_pwr_mgr(const uhd::direction_t trx);

private:
    //! Locks access to the API
    mutable std::recursive_mutex _lock;

    std::string _get_trx_string(const direction_t dir) const;

    void _validate_master_clock_rate_args();
    void _init_mpm();
    void _init_mpm_sensors(const direction_t dir, const size_t chan_idx);
    void _init_prop_tree();
    fs_path _get_db_fe_path(const size_t chan, const uhd::direction_t dir) const;

    //! Reference to the MB controller
    uhd::rfnoc::mpmd_mb_controller::sptr _mb_control;

    //! Reference to the RPC client
    uhd::usrp::x400_rpc_iface::sptr _rpcc;
    uhd::usrp::dboard_base_rpc_iface::sptr _db_rpcc;

    //! Reference to the MB timekeeper
    uhd::rfnoc::mpmd_mb_controller::mpmd_timekeeper::sptr _x4xx_timekeeper;

    std::string _radio_slot;
    std::string _rpc_prefix;

    //! Reference to this radio block's RFDC control
    x400::rfdc_control::sptr _rfdcc;

    uhd::usrp::x400::x400_dboard_iface::sptr _daughterboard;

    uhd::features::adc_self_calibration_iface::sptr _adc_self_calibration;

    x400::gpio_control::sptr _gpios;

    class fpga_onload : public uhd::features::fpga_load_notification_iface
    {
    public:
        using sptr = std::shared_ptr<fpga_onload>;

        fpga_onload(size_t num_channels,
            uhd::features::adc_self_calibration_iface::sptr adc_self_cal,
            std::string unique_id);

        void onload() override;

    private:
        const size_t _num_channels;
        uhd::features::adc_self_calibration_iface::sptr _adc_self_cal;
        const std::string _unique_id;
        std::string get_unique_id() const
        {
            return _unique_id;
        }
    };

    fpga_onload::sptr _fpga_onload;
};

}} // namespace uhd::rfnoc