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
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
|
//
// Copyright 2014-2016 Ettus Research LLC
// Copyright 2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#ifndef INCLUDED_LIBUHD_RFNOC_RADIO_CTRL_IMPL_HPP
#define INCLUDED_LIBUHD_RFNOC_RADIO_CTRL_IMPL_HPP
#include <uhd/rfnoc/radio_ctrl.hpp>
#include <uhd/types/direction.hpp>
#include <uhdlib/usrp/cores/rx_vita_core_3000.hpp>
#include <uhdlib/usrp/cores/tx_vita_core_3000.hpp>
#include <uhdlib/usrp/cores/time_core_3000.hpp>
#include <uhdlib/usrp/cores/gpio_atr_3000.hpp>
#include <boost/thread.hpp>
#include <mutex>
//! Shorthand for radio block constructor
#define UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR_DECL(CLASS_NAME) \
CLASS_NAME##_impl(const make_args_t &make_args);
#define UHD_RFNOC_RADIO_BLOCK_CONSTRUCTOR(CLASS_NAME) \
CLASS_NAME##_impl::CLASS_NAME##_impl( \
const make_args_t &make_args \
) : block_ctrl_base(make_args), radio_ctrl_impl()
namespace uhd {
namespace rfnoc {
/*! \brief Provide access to a radio.
*
*/
class radio_ctrl_impl : public radio_ctrl
{
public:
/************************************************************************
* Structors
***********************************************************************/
radio_ctrl_impl();
virtual ~radio_ctrl_impl() {};
/************************************************************************
* Public Radio API calls
***********************************************************************/
virtual double set_rate(double rate);
virtual void set_tx_antenna(const std::string &ant, const size_t chan);
virtual void set_rx_antenna(const std::string &ant, const size_t chan);
virtual double set_tx_frequency(const double freq, const size_t chan);
virtual double set_rx_frequency(const double freq, const size_t chan);
virtual double set_tx_gain(const double gain, const size_t chan);
virtual double set_rx_gain(const double gain, const size_t chan);
virtual double set_tx_bandwidth(const double bandwidth, const size_t chan);
virtual double set_rx_bandwidth(const double bandwidth, const size_t chan);
virtual double get_rate() const;
virtual std::string get_tx_antenna(const size_t chan) /* const */;
virtual std::string get_rx_antenna(const size_t chan) /* const */;
virtual double get_tx_frequency(const size_t) /* const */;
virtual double get_rx_frequency(const size_t) /* const */;
virtual double get_tx_gain(const size_t) /* const */;
virtual double get_rx_gain(const size_t) /* const */;
virtual double get_tx_bandwidth(const size_t) /* const */;
virtual double get_rx_bandwidth(const size_t) /* const */;
virtual std::vector<std::string> get_rx_lo_names(const size_t chan);
virtual std::vector<std::string> get_rx_lo_sources(const std::string &name, const size_t chan);
virtual freq_range_t get_rx_lo_freq_range(const std::string &name, const size_t chan);
virtual void set_rx_lo_source(const std::string &src, const std::string &name, const size_t chan);
virtual const std::string get_rx_lo_source(const std::string &name, const size_t chan);
virtual void set_rx_lo_export_enabled(bool enabled, const std::string &name, const size_t chan);
virtual bool get_rx_lo_export_enabled(const std::string &name, const size_t chan);
virtual double set_rx_lo_freq(const double freq, const std::string &name, const size_t chan);
virtual double get_rx_lo_freq(const std::string &name, const size_t chan);
virtual std::vector<std::string> get_tx_lo_names(const size_t chan);
virtual std::vector<std::string> get_tx_lo_sources(const std::string &name, const size_t chan);
virtual freq_range_t get_tx_lo_freq_range(const std::string &name, const size_t chan);
virtual void set_tx_lo_source(const std::string &src, const std::string &name, const size_t chan);
virtual const std::string get_tx_lo_source(const std::string &name, const size_t chan);
virtual void set_tx_lo_export_enabled(const bool enabled, const std::string &name, const size_t chan);
virtual bool get_tx_lo_export_enabled(const std::string &name, const size_t chan);
virtual double set_tx_lo_freq(const double freq, const std::string &name, const size_t chan);
virtual double get_tx_lo_freq(const std::string &name, const size_t chan);
void set_time_now(const time_spec_t &time_spec);
void set_time_next_pps(const time_spec_t &time_spec);
void set_time_sync(const uhd::time_spec_t &time);
time_spec_t get_time_now();
time_spec_t get_time_last_pps();
virtual void set_time_source(const std::string &source);
virtual std::string get_time_source();
virtual std::vector<std::string> get_time_sources();
virtual void set_clock_source(const std::string &source);
virtual std::string get_clock_source();
virtual std::vector<std::string> get_clock_sources();
virtual std::vector<std::string> get_gpio_banks() const;
virtual void set_gpio_attr(
const std::string &bank,
const std::string &attr,
const uint32_t value,
const uint32_t mask
);
virtual uint32_t get_gpio_attr(const std::string &bank, const std::string &attr);
void enable_rx_timestamps(const bool, const size_t);
/***********************************************************************
* Block control API calls
**********************************************************************/
void set_rx_streamer(bool active, const size_t port);
void set_tx_streamer(bool active, const size_t port);
void issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd, const size_t port);
virtual double get_input_samp_rate(size_t /* port */) { return get_rate(); }
virtual double get_output_samp_rate(size_t /* port */) { return get_rate(); }
double _get_tick_rate() { return get_rate(); }
std::vector<size_t> get_active_rx_ports();
bool in_continuous_streaming_mode(const size_t chan) { return _continuous_streaming.at(chan); }
void rx_ctrl_clear_cmds(const size_t port) { sr_write(regs::RX_CTRL_CLEAR_CMDS, 0, port); }
protected: // TODO see what's protected and what's private
void _register_loopback_self_test(size_t chan);
/***********************************************************************
* Registers
**********************************************************************/
struct regs {
static inline uint32_t sr_addr(const uint32_t offset) { return offset * 4; }
static inline uint32_t rb_addr(const uint32_t offset) { return offset * 8; }
static const uint32_t BASE = 128;
// defined in radio_core_regs.vh
static const uint32_t TIME = 128; // time hi - 128, time lo - 129, ctrl - 130
static const uint32_t CLEAR_CMDS = 131; // Any write to this reg clears the command FIFO
static const uint32_t LOOPBACK = 132;
static const uint32_t TEST = 133;
static const uint32_t CODEC_IDLE = 134;
static const uint32_t TX_CTRL_ERROR_POLICY = 144;
static const uint32_t RX_CTRL_CMD = 152;
static const uint32_t RX_CTRL_TIME_HI = 153;
static const uint32_t RX_CTRL_TIME_LO = 154;
static const uint32_t RX_CTRL_HALT = 155;
static const uint32_t RX_CTRL_MAXLEN = 156;
static const uint32_t RX_CTRL_CLEAR_CMDS = 157;
static const uint32_t RX_CTRL_OUTPUT_FORMAT= 158;
static const uint32_t MISC_OUTS = 160;
static const uint32_t DACSYNC = 161;
static const uint32_t SPI = 168;
static const uint32_t LEDS = 176;
static const uint32_t FP_GPIO = 184;
static const uint32_t GPIO = 192;
// NOTE: Upper 32 registers (224-255) are reserved for the output settings bus for use with
// device specific front end control
// frontend control: needs rethinking TODO
//static const uint32_t TX_FRONT = BASE + 96;
//static const uint32_t RX_FRONT = BASE + 112;
//static const uint32_t READBACK = BASE + 127;
static const uint32_t RB_TIME_NOW = 0;
static const uint32_t RB_TIME_PPS = 1;
static const uint32_t RB_TEST = 2;
static const uint32_t RB_CODEC_READBACK = 3;
static const uint32_t RB_RADIO_NUM = 4;
static const uint32_t RB_MISC_IO = 16;
static const uint32_t RB_SPI = 17;
static const uint32_t RB_LEDS = 18;
static const uint32_t RB_DB_GPIO = 19;
static const uint32_t RB_FP_GPIO = 20;
};
/***********************************************************************
* Block control API calls
**********************************************************************/
void _update_spp(int spp);
inline size_t _get_num_radios() const {
return std::max(_num_rx_channels, _num_tx_channels);
}
inline timed_wb_iface::sptr _get_ctrl(size_t radio_num) const {
return _perifs.at(radio_num).ctrl;
}
inline bool _is_streamer_active(uhd::direction_t dir, const size_t chan) const {
switch (dir) {
case uhd::TX_DIRECTION:
return _tx_streamer_active.count(chan) ? _tx_streamer_active.at(chan) : false;
case uhd::RX_DIRECTION:
return _rx_streamer_active.count(chan) ? _rx_streamer_active.at(chan) : false;
case uhd::DX_DIRECTION:
return (_tx_streamer_active.count(chan) and _rx_streamer_active.count(chan)) ?
_rx_streamer_active.at(chan) and _tx_streamer_active.at(chan) : false;
default:
return false;
}
}
virtual bool check_radio_config() { return true; };
//! There is always only one time core per radio
time_core_3000::sptr _time64;
std::mutex _mutex;
size_t _num_tx_channels;
size_t _num_rx_channels;
std::vector<bool> _continuous_streaming;
private:
/************************************************************************
* Peripherals
***********************************************************************/
//! Stores pointers to all streaming-related radio cores
struct radio_perifs_t
{
timed_wb_iface::sptr ctrl;
};
std::map<size_t, radio_perifs_t> _perifs;
// Cached values
double _tick_rate;
std::map<size_t, std::string> _tx_antenna;
std::map<size_t, std::string> _rx_antenna;
std::map<size_t, double> _tx_freq;
std::map<size_t, double> _rx_freq;
std::map<size_t, double> _tx_gain;
std::map<size_t, double> _rx_gain;
std::map<size_t, double> _tx_bandwidth;
std::map<size_t, double> _rx_bandwidth;
}; /* class radio_ctrl_impl */
}} /* namespace uhd::rfnoc */
#endif /* INCLUDED_LIBUHD_RFNOC_RADIO_CTRL_IMPL_HPP */
|