aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/common/ad9361_ctrl.hpp
blob: 8dbb909f7616493ee253bb423c498a8c50be2324 (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
//
// Copyright 2012-2014 Ettus Research LLC
//
// SPDX-License-Identifier: GPL-3.0
//

#ifndef INCLUDED_AD9361_CTRL_HPP
#define INCLUDED_AD9361_CTRL_HPP

#include <uhd/transport/zero_copy.hpp>
#include <uhd/types/ranges.hpp>
#include <uhd/types/serial.hpp>
#include <uhd/types/sensors.hpp>
#include <uhd/exception.hpp>
#include <boost/shared_ptr.hpp>
#include <ad9361_device.h>
#include <string>
#include <complex>
#include <uhd/types/filters.hpp>
#include <vector>

namespace uhd { namespace usrp {

/*! AD936x Control Interface
 *
 * This is a convenient way to access the AD936x RF IC.
 * It basically encodes knowledge of register values etc. into
 * accessible API calls.
 *
 * \section ad936x_which The `which` parameter
 *
 * Many function calls require a `which` parameter to select
 * the RF frontend. Valid values for `which` are:
 * - RX1, RX2
 * - TX1, TX2
 *
 * Frontend numbering is as designed by the AD9361.
 */
class ad9361_ctrl : public boost::noncopyable
{
public:
    typedef boost::shared_ptr<ad9361_ctrl> sptr;

    virtual ~ad9361_ctrl(void) {};

    //! make a new codec control object
    static sptr make_spi(
        ad9361_params::sptr client_settings,
        uhd::spi_iface::sptr spi_iface,
        uint32_t slave_num
    );

    virtual void set_timed_spi(uhd::spi_iface::sptr spi_iface, uint32_t slave_num) = 0;
    virtual void set_safe_spi(uhd::spi_iface::sptr spi_iface, uint32_t slave_num) = 0;

    //! Get a list of gain names for RX or TX
    static std::vector<std::string> get_gain_names(const std::string &/*which*/)
    {
        return std::vector<std::string>(1, "PGA");
    }

    //! get the gain range for a particular gain element
    static uhd::meta_range_t get_gain_range(const std::string &which)
    {
        if(which[0] == 'R') {
            return uhd::meta_range_t(0.0, 76.0, 1.0);
        } else {
            return uhd::meta_range_t(0.0, 89.75, 0.25);
        }
    }

    //! get the freq range for the frontend which
    static uhd::meta_range_t get_rf_freq_range(void)
    {
        return uhd::meta_range_t(50e6, 6e9);
    }

    //! get the filter range for the frontend which
    static uhd::meta_range_t get_bw_filter_range(const std::string &/*which*/)
    {
        return uhd::meta_range_t(200e3, 56e6);
    }

    //! get the clock rate range for the frontend
    static uhd::meta_range_t get_clock_rate_range(void)
    {
        return uhd::meta_range_t(
                ad9361_device_t::AD9361_MIN_CLOCK_RATE,
                ad9361_device_t::AD9361_MAX_CLOCK_RATE
        );
    }

    //! set the filter bandwidth for the frontend's analog low pass
    virtual double set_bw_filter(const std::string &/*which*/, const double /*bw*/) = 0;

    //! set the gain for a particular gain element
    virtual double set_gain(const std::string &which, const double value) = 0;

    //! Enable or disable the AGC module
    virtual void set_agc(const std::string &which, bool enable) = 0;

    //! configure the AGC module to slow or fast mode
    virtual void set_agc_mode(const std::string &which, const std::string &mode) = 0;

    //! set a new clock rate, return the exact value
    virtual double set_clock_rate(const double rate) = 0;

    //! set which RX and TX chains/antennas are active
    virtual void set_active_chains(bool tx1, bool tx2, bool rx1, bool rx2) = 0;

    //! tune the given frontend, return the exact value
    virtual double tune(const std::string &which, const double value) = 0;

    //! set the DC offset for I and Q manually
    void set_dc_offset(const std::string &, const std::complex<double>)
    {
        //This feature should not be used according to Analog Devices
        throw uhd::runtime_error("ad9361_ctrl::set_dc_offset this feature is not supported on this device.");
    }

    //! enable or disable the BB/RF DC tracking feature
    virtual void set_dc_offset_auto(const std::string &which, const bool on) = 0;

    //! set the IQ correction value manually
    void set_iq_balance(const std::string &, const std::complex<double>)
    {
        //This feature should not be used according to Analog Devices
        throw uhd::runtime_error("ad9361_ctrl::set_iq_balance this feature is not supported on this device.");
    }

    //! enable or disable the quadrature calibration
    virtual void set_iq_balance_auto(const std::string &which, const bool on) = 0;

    //! get the current frequency for the given frontend
    virtual double get_freq(const std::string &which) = 0;

    //! turn on/off Catalina's data port loopback
    virtual void data_port_loopback(const bool on) = 0;

    //! read internal RSSI sensor
    virtual sensor_value_t get_rssi(const std::string &which) = 0;

    //! read the internal temp sensor
    virtual sensor_value_t get_temperature() = 0;

    //! List all available filters by name
    virtual std::vector<std::string> get_filter_names(const std::string &which) = 0;

    //! Return a list of all filters
    virtual filter_info_base::sptr get_filter(const std::string &which, const std::string &filter_name) = 0;

    //! Write back a filter
    virtual void set_filter(const std::string &which, const std::string &filter_name, const filter_info_base::sptr) = 0;

    virtual void output_digital_test_tone(bool enb) = 0;
};

}}

#endif /* INCLUDED_AD9361_CTRL_HPP */